MvvmCross: Unit-testing services with plugins - unit-testing

I am creating a cross-platform project with MvvmCross v3 and Xamarin solution and i would like to create some unit-tests.
This seems a bit outdated, so i was trying to follow this and it worked as expected.
However, I am now making an attempt to unit-test some of my domain services, which are dependent on platform specific MvvvCross plugins (e.g ResourceLoader).
Running the test results in the following exception:
Cirrious.CrossCore.Exceptions.MvxException: Failed to resolve type
Cirrious.CrossCore.Plugins.IMvxPluginManager.
I assume that IMvxPluginManager is probably registered in the Setup flow, and that I need to include platform implementation of the plugins in my project, yet I was wondering what would be the preferred way of setting up my unit-test project? Is there something that I am missing?
Is there any updated tutorial for the above task?
Are there already any plugin platform extensions that supports test environment, or should I make an attempt to write them by myself?

In general, you shouldn't be loading the plugins or a real MvxPluginManager during your service tests.
Instead your unit tests should be registering mock types for the interfaces that your services need to use.
var mock = new Mock<INeedToUse>();
// use mock.Setup methods
Ioc.RegisterSingleton<INeedToUse>(mock.Object);
// or you can use constructor dependency injection on INeedToUse instead
You can also register a mock IMvxPluginManager if you really need to, but in the majority of cases I don't believe you should need that. If you've got a case where you absolutely need it, please post a code sample - it's easier to talk in code than text.

This scenario should be well possible. I wanted to UnitTest my SqlLite service implementation. I did the following to get it to work:
Create a Visual Studio unit test project
Add a reference to .Core portable library project
Add a nuget reference To MvvmCross Test Helper
Add a nugget reference to MvvmCross SqlLite Plugin
( this will make use of the WPF implementation of SqlLite)
Download the SqlLite windows library and copy these into your test project
Sql Lite Download location
And make sure to add the sqllite3.dll to the root of your unit test project and set the "Copy to Output Library" to "Copy always". This will make sure the actual sqllite database is copied to the unit test dll location. (Check that the DLL is copied to your bin/debug folder)
Then write you unit test the following way:
[TestClass]
public class SqlServiceTests:MvxIoCSupportingTest
{
private readonly ISQLiteConnectionFactory _factory;
public SqlServiceTests()
{
base.ClearAll();
_factory = new MvxWpfSqLiteConnectionFactory();
Ioc.RegisterSingleton<ISQLiteConnectionFactory>(_factory);
}
[TestMethod]
public void YourSqlLiteTest()
{
// Arrange
var si = new SqlDataService(_factory);
var list = si.GetOrderList();
}
}
I haven't tested this with my viewmodel. By using the IoC.RegisterSingleton method the SqlConnectionFactory should be readyli available for your viewmodels.

Related

Is there any way to create integration test for libGDX application?

I apologize if the question is duplicated, but I can't find any information about this.
I know that I can use JUnit to create simple unit tests, but I can't run it on android/iOS devices. If I understand correctly, I can use Instrumented Unit Tests, but they are for android platform only. In this case, I can't test functions from libGDX core (am I wrong?). So, I'm interested, how can I run my tests on devices?
Testing libGDX applications is not an easy topic but with a good architecture it is possible. The crucial point is to separate the rendering part from the business logic you want to test. Rendering always requires an OpenGL context and will just break if you try to run it without that. You can actually write tests that require OpenGL if you don't plan to run them on a headless build server but just on your desktop.
That being said, testing of libGDX apps is mostly centered around the usage of HeadlessApplication that makes your libGDX-dependent code runnable in your test environment. If you want to start he whole game in a test, you need a headless version of it (here "MyGameHeadlessApplication"). Then you can initialize it like this:
private MyGameHeadlessApplication application;
#Before
public void setUp() throws Exception {
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
config.renderInterval = 1F / 30F;
application = new MyGameHeadlessApplication();
new HeadlessApplication(this.application , config);
}
For testing smaller parts that depend on libGDX, there is a very conventient library available: The gdx-testing project contains a GdxTestRunner that wraps your tests in a HeadlessApplication and allows you something like this (from the gdx-testing example):
#RunWith(GdxTestRunner.class)
public class MySuperTestClass {
#Test
public void bestTestInHistory() {
// libgdx dependent code runs here
}
}
On top of that I had a little problem with my assets folder that couldn't be found in the tests in the first place. I fixed that by setting workingDir for tests in my build.gradle. And of cours make sure to have all the needed dependencies (also e.g. box2d if you need that in your tests). In my setup I have all tests in the "core" project:
project(":core") {
apply plugin: "java"
test {
project.ext.assetsDir = new File("./assets")
workingDir = project.ext.assetsDir
}
dependencies {
testCompile "com.badlogicgames.gdx:gdx-backend-headless:$gdxVersion"
testCompile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
testCompile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"
// ... more dependencies here ...
See also Unit-testing of libgdx-using classes

Unconstrained Isolation (mocking) framework for dotnet core

I'm working on a dotnet core project, trying to mock some third party classes in my Xunit.net tests. The class I'm trying to fake is not mockable through constrained frameworks like Moq or NSubstitute. So I need an unconstrained framework to do that.
Say I want to fake DateTime.Now in my .net core test projects.
In .net 4.5 we have MSFakes(Moles), Smocks, etc. None of them support dotnet core framework yet. Shim is not ported to dotnet core yet.
Anyone knows any isolation framework or technique that will achieve my goal for .NET Core at the present time?
You could try a different way: wrap those third party libs with your own interfaces and wrapper classes. Then use a dummy object implementing that interface.
Things become more complicated with static properties like DateTime.Now. But it works similar: define an ITimeProvider interface with a Now property. Add a DateTimeWrapper : ITimeProvider with a public DateTime Now => DateTime.Now;, and - for convenience, but not required - a static class around it, e.g.
static class MyClock
{
static ITimeProvider _Instance;
static void SetInstanceForTesting(ITimeProvider instance)
{ _Instance = instance; }
static DateTime Now => _Instance.Now;
}
Alternatively, you may inject an ITimeProvider instance to the objects needing it.
A somewhat late reply, but for anyone else looking after the same kind of functionality I would recommend the open source git project prig: https://github.com/urasandesu/Prig It can fake static methods (they even have an example of faking and isolating DateTime.Now) and is an alternative to Microsoft Fakes, TypeMock and JustMock (all who cost money or require ultimate editions of visual studio to use).
Pose is an option. It's free full in memory
Https://GitHub.com/tonerdo/pose

How to avoid replicating configuration settings from web.config in unit tests

I have a web project which reads multiple configuration keys from web.config. These settings are related to the rules implemented in the project. When the unit test invokes the model classes in the web project it ends up reading the app.config from the unit test project. So I have to replicate the keys in app.config in the unit test project. Is it better to move the configuration information to an external file in the web project to avoid the copies of the configuration information?
Thanks in advance.
When testing web apps I end up doing the same as you, copying settings into the app.config file of the test project. There's nothing wrong with that.
The alternative would be to mock the config settings where they would be used, but this can be cumbersome, however it is still a valid approach. I tend to just keep it simple and create an app.config file.
I would use wrapper class which returns those settings. Example below
public interface ISettingStorage
{
string GetSetting(string name);
}
public class SettingStorage : ISettingStorage
{
public string GetSetting(string name)
{
// read the actual setting from the web.config
}
}
This way you can mock the ISettingStorage in your unit tests to return whatever values you want. It will also slightly speed up the unit tests because there is no disk I/O.

MVC 3: How to learn how to test with NUnit, Ninject, and Moq?

Short version of my questions:
Can anyone point me toward some good, detailed sources from which I
can learn how to implement testing in my MVC 3 application, using
NUnit, Ninject 2, and Moq?
Can anyone here help clarify for me how Controller-Repository
decoupling, mocking, and dependency injection work together?
Longer version of my questions:
What I'm trying to do ...
I am currently beginning to create an MVC 3 application, which will use Entity Framework 4, with a database first approach. I want to do this right, so I am trying to design the classes, layers, etc., to be highly testable. But, I have little to no experience with unit testing or integration testing, other than an academic understanding of them.
After lots of research, I've settle on using
NUnit as my testing framework
Ninject 2 as my dependency injection framework
Moq as my mocking framework.
I know the topic of which framework is best, etc., could enter into this, but at this point I really don't know enough about any of it to form a solid opinion. So, I just decided to go with these free solutions which seem to be well liked and well maintained.
What I've learned so far ...
I've spent some time working through some of this stuff, reading resources such as:
Implementing the Repository and Unit of Work Patterns in an
ASP.NET MVC Application
Building Testable ASP.NET MVC Applications
NerdDinner Step 12: Unit Testing
Using Repository and Unit of Work patterns with Entity Framework
4.0
From these resources, I've managed to workout the need for a Repository pattern, complete with repository interfaces, in order to decouple my controllers and my data access logic. I have written some of that into my application already, but I admit I am not clear as to the mechanics of the whole thing, and whether I am doing this decoupling in support of mocking, or dependency injection, or both. As such, I certainly wouldn't mind hearing from you guys about this too. Any clarity I can gain on this stuff will help me at this point.
Where things got muddy for me ...
I thought I was grasping this stuff pretty well until I started trying to wrap my head around Ninject, as described in Building Testable ASP.NET MVC Applications, cited above. Specifically, I got completely lost around the point in which the author begins describing the implementation of a Service layer, about half way into the document.
Anyway, I am now looking for more resources to study, in order to try to get various perspectives around this stuff until it begins to make sense to me.
Summarizing all of this, boiling it down to specific questions, I am wondering the following:
Can anyone point me toward some good, detailed sources from which I
can learn how to implement testing in my MVC 3 application, using
NUnit, Ninject 2, and Moq?
Can anyone here help clarify for me how Controller-Repository
decoupling, mocking, and dependency injection work together?
EDIT:
I just discovered the Ninject official wiki on Github, so I'm going to start working through that to see if it starts clarifying things for me. But, I'm still very interested in the SO community thoughts on all of this :)
If you are using the Ninject.MVC3 nuget package, then some of the article you linked that was causing confusion will not be required. That package has everything you need to start injecting your controllers which is probably the biggest pain point.
Upon installing that package, it will create a NinjectMVC3.cs file in the App_Start folder, inside that class is a RegisterServices method. This is where you should create the bindings between your interfaces and your implementations
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IRepository>().To<MyRepositoryImpl>();
kernel.Bind<IWebData>().To<MyWebDAtaImpl>();
}
Now in your controller you can use constructor injection.
public class HomeController : Controller {
private readonly IRepository _Repo;
private readonly IWebData _WebData;
public HomeController(IRepository repo, IWebData webData) {
_Repo = repo;
_WebData = webData;
}
}
If you are after very high test coverage, then basically anytime one logical piece of code (say controller) needs to talk to another (say database) you should create an interface and implementation, add the definition binding to RegisterService and add a new constructor argument.
This applies not only to Controller, but any class, so in the example above if your repository implementation needed an instance of WebData for something, you would add the readonly field and the constructor to your repository implementation.
Then when it comes to testing, what you want to do is provide mocked version of all required interfaces, so that the only thing you are testing is the code in the method you are writing the test for. So in my example, say that IRepository has a
bool TryCreateUser(string username);
Which is called by a controller method
public ActionResult CreateUser(string username) {
if (_Repo.TryCreateUser(username))
return RedirectToAction("CreatedUser");
else
return RedirectToAction("Error");
}
What you are really trying to test here is that if statement and the return types, you do not want to have to create a real repository that will return true or false based on special values you give it. This is where you want to mock.
public void TestCreateUserSucceeds() {
var repo = new Mock<IRepository>();
repo.Setup(d=> d.TryCreateUser(It.IsAny<string>())).Returns(true);
var controller = new HomeController(repo);
var result = controller.CreateUser("test");
Assert.IsNotNull(result);
Assert.IsOfType<RedirectToActionResult>(result)
Assert.AreEqual("CreatedUser", ((RedirectToActionResult)result).RouteData["Action"]);
}
^ That won't compile for you as I know xUnit better, and do not remember the property names on RedirectToActionResult from the top of my head.
So to sum up, if you want one piece of code to talk to another, whack an interface in between. This then allows you to mock the second piece of code so that when you test the first you can control the output and be sure you are testing only the code in question.
I think it was this point that really made the penny drop for me with all this, you do this not necessarily becase the code demands it, but because the testing demands it.
One last piece of advice specific to MVC, any time you need to access the basic web objects, HttpContext, HttpRequest etc, wrap all these behind an interface as well (like the IWebData in my example) because while you can mock these using the *Base classes, it becomes painful very quickly as they have a lot of internal dependencies you also need to mock.
Also with Moq, set the MockBehaviour to Strict when creating mocks and it will tell you if anything is being called that you have not provided a mock for.
Here is the application that I'm creating. It is open source and available on github, and utilizes all of the required stuff - MVC3, NUnit, Moq, Ninject - https://github.com/alexanderbeletsky/trackyt.net/tree/master/src
Contoller-Repository decoupling is simple. All data operations are moved toward the Repository. Repository is an implementation of some IRepository type. The controller never creates repositories inside itself (with the new operator) but rather receives them either by constructor argument or property.
.
public class HomeController {
public HomeController (IUserRepository users) {
}
}
This technique is called "Inversion of Control." To support inversion of control you have to provide some "Dependency Injection" framework. Ninject is a good one. Inside Ninject you associate some particular interface with an implementation class:
Bind<IUserRepository>().To<UserRepository>();
You also substitute the default controller factory with your custom one. Inside the custom one you delegate the call to the Ninject kernel:
public class TrackyControllerFactory : DefaultControllerFactory
{
private IKernel _kernel = new StandardKernel(new TrackyServices());
protected override IController GetControllerInstance(
System.Web.Routing.RequestContext requestContext,
Type controllerType)
{
if (controllerType == null)
{
return null;
}
return _kernel.Get(controllerType) as IController;
}
}
When the MVC infrastructure is about to create a new controller, the call is delegated to the custom controller factory GetControllerInstance method, which delegates it to Ninject. Ninject sees that to create that controller the constructor has one argument of type IUserRepository. By using the declared binding, it sees that "I need to create a UserRepository to satisfy the IUserRepository need." It creates the instance and passes it to the constructor.
The constructor is never aware of what exact instance would be passed inside. It all depends on the binding you provide for that.
Code examples:
https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Infrastructure/TrackyServices.cs https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Infrastructure/TrackyControllerFactory.cs https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Controllers/LoginController.cs
Check it out : DDD Melbourne video - New development workflow
The whole ASP.NET MVC 3 development process was very well presented.
The third party tools I like most are:
Using NuGet to install Ninject to enable DI throughout the MVC3
framework
Using NuGet to install nSubstite to create mocks to enable unit
testing

Can I unit test a method that makes Sitecore context calls?

I'm working on a web application that is built over Sitecore CMS. I was wondering if we could unit test for example a method that takes some data from Sitecore makes some processing with it and spits out a result. I would like to test all the logic within the method via a unit test.
I pretty confused after searching the internet wide and deep. Some say that this kind of testing is actually integration testing and not unit testing and I should test only the code that has no Sitecore calls, others say that this is not possible because the Sitecore context would be missing.
I would like to ask for your help experienced fellow programmers:
Can I unit test a method that contains Sitecore calls ? If YES, how ? If NO, why ? Is there any workaround ?
The project is at its beginning, so there will be no problem in choosing between unit testing frameworks such as MSTest or Nunit, if it is the case that the solution is related to the unit testing framework of choice.
It's pretty hard to find out anything about Sitecore without providing email and living through the sales pitch, so I'll just provide a generic approach on how to do something like this.
First and foremost, you assume that the Sitecore API is guaranteed to work - i.e. it's a framework - and you don't unit test it. You should be unit testing your interactions with it.
Then, download MOQ and read the quick start on how to use it. This is my preferred mocking framework. Feel free to use other frameworks if you wish.
Hopefully, Sitecore API provides a way for you to create data objects without dealing with persistence - i.e. to simply create a new instance of whatever it is you are interested in. Here is my imaginary API:
public class Post {
public string Body {get;set;}
public DateTime LastModified {get;set;}
public string Title {get;set;}
}
public interface ISiteCorePosts {
public IEnumerable<Post> GetPostsByUser(int userId);
}
In this case unit testing should be fairly easy. With a bit of Dependency Injection, you can inject the SiteCore interfaces into your component and then unit test it.
public class MyPostProcessor {
private readonly ISiteCorePosts m_postRepository;
public MyPostProcessor(ISiteCorePosts postRepository) {
m_postRepository = postRepository;
}
public void ProcessPosts(int userId) {
var posts = m_postRepository.GetPostsByUser(userId);
//do something with posts
}
}
public class MyPostProcessorTest {
[TestMethod]
ProcessPostsShouldCallGetPostsByUser() {
var siteCorePostsMock = new Mock<ISiteCorePosts>();
//Sets up the mock to return a list of posts when called with userId = 5
siteCorePostsMock.Setup(m=>m.GetPostsByUser(5)).Returns(new List<Post>{/*fake posts*/});
MyPostProcessor target = new MyPostProcessor(siteCorePostsMock.Object);
target.ProcessPosts(5);
//Verifies that all setups are called
siteCorePostsMock.VerifyAll();
}
}
If ISiteCorePosts is not, in fact, an interface and is a concrete class whose methods are not virtual and thus cannot be mocked, you will need to use Facade pattern to wrap the SiteCore interaction to make it more testing friendly.
public class SiteCorePostsFacade {
SiteCorePosts m_Posts = new SiteCorePosts();
//important - make this method virtual so it can be mocked without needing an interface
public virtual IEnumerable<Post> GetPostsByUser(int userId) {
return m_Posts.GetPostsByUser(userId);
}
}
You then proceed to use SiteCorePostsFacade as though it was an interface in the previous example. Good thing about MOQ is that it allows you to mock concrete classes with virtual methods, not just interfaces.
With this approach, you should be able to inject all sorts of data into your application to test all interactions with SiteCore API.
we have used a custom WebControl placed on a WebForm for our integration tests some years now, which wraps the NUnit Test Suite runner functionality much like the NUnit GUI. It show a pretty grid of executed tests with links to fixtures and categories to execute specific tests. Its created much like described here http://adeneys.wordpress.com/2010/04/13/new-technique-for-unit-testing-renderings-in-sitecore/ (the custom test runner part). Our implementation can also return raw NUnit xml for further processing by for example a build server.
I've tried MSTest a while back and it also works when specified that it should launch a WebDev / IIS site to test. It works but is extremely slow compared to above solution.
Happy testing!
Short answer:
You need to mock calls to SiteCore CMS.
Long answer:
I am not aware about SiteCore CMS. But, from your question looks like it is something that is external to your application. Components external to your system should always be used via interface. This has two benefits:
If you want to use another CMS system, you can easily do as your application is just talking to an interface.
It helps you with behavior testing by mocking the interface.
The code you write is your responsibility and hence you should only unit test that piece of code. Your unit tests should ensure that your code calls appropriate SiteCode CMS methods in various scenarios (behavior tests). You can do this using mocking. I use moq for mocking.
As tugga said, it depends upon how tightly the code you want to test is coupled to SiteCore. If it's something like:
SomeSiteCoreService siteCoreDependency = new SomeSiteCoreService()
Then this would be very difficult to test. If SiteCore provides you an interface, then you have more flexibility to unit test it. You could pass the implementation into your method either (contstructor, class property, or method parameter) and then you can send in a fake implementation of that service.
If they do not provide you with an interface, then you have to do a little more work. You would write an adapter interface of your own and the default implementation would delegate to the 3rd party dependency.
public interface ICMSAdapter{
void DoSomethingWithCMS()
}
public class SiteCoreCMSAdapter: ICMSAdapter{
SiteCoreService _cms = new SiteCoreService();
public void DoSomethingWithCMS(){
_cms.DoSomething();
}
That keeps your 3rd party dependencies at arms length and provides seams to all sorts of cool things, like unit tests and you do interception style architecture and do your own thing before and after the call.
}
I was able to get unit tests to interact with sitecore api in VS 2015. The same test throws a StackOverflow exception when run in VS 2012.
For example, this method call runs fine in VS2015 but not VS2015:
Context.SetActiveSite("mysite");
quick note: this assumes you have a site named mysite setup in your config file