How to test whether my factories are properly bound? - unit-testing

Using Ninject, I have the following and wish to test using FluentAssertions:
[Test]
public void InterfacesEndingWithFactoryShouldBeBoundAsFactories() {
// Given
IKernel kernel = new StandardKernel();
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.FullName.Contains("Tests")))
.SelectAllInterfaces()
.EndingWith("Factory")
.BindToFactory()
);
// When
var factory = kernel.Get<ICustomerManagementPresenterFactory>();
// Then
factory.Should().NotBeNull();
}
Is there any good ways to test whether the factories are actually bound properly?

I wrote an extension package for Fluent Assertions to test my Ninject bindings. Using it your test could be rewritten like this:
[Test]
public void InterfacesEndingWithFactoryShouldBeBoundAsFactories() {
// Given
IKernel kernel = new StandardKernel();
kernel.Bind(services => services
.From(AppDomain.CurrentDomain
.GetAssemblies()
.Where(a => !a.FullName.Contains("Tests")))
.SelectAllInterfaces()
.EndingWith("Factory")
.BindToFactory()
);
// When
// Then
kernel.Should().Resolve<ICustomerManagementPresenterFactory>().WithSingleInstance()
}
As suggested by #Will Marcouiller, I would also extract the code to bootstrap the kernel into it's own class so it can be invoked in your app's composition root and in your unit tests.

First off, there is no ninject infrastructure to test which types are affected and which not. Unit testing is very complicated due to the fluent syntax and it's many interfaces which are returned when calling a method. So all you can practically do is integration testing.
Now, in my opinion, the From(...) is problematic. If you'd create a component where you could replace the assemblies you pass to From , create an extra test assembly containing a few types, and then test whether lets say interface IFoo is not bound, interface IFooFactory is bound, class Foo is not bound,.. you would have a functioning integration test.
Consider however, that if there is no binding for IFooFactory and SomeClass uses IFooFactory as constructor argument, ninject will throw an exception. Now if you have a composition root simply starting up the application will tell you whether the necessary bindings exist or not.
This test is even more useful than the factory convention integration test. Consider if someone accidentally bound the factory, manually, too. This won't show up with the convention-integration test, but starting the application, ninject will throw an exception stating that there are multiple bindings for this one interface.

Related

What is exactly mocking in unit testing?

I am trying to test an http server functionality and this is the first time I get exposed to the notions of mocks, stubs and fakes. I'm reading this book that it says mocking is describing the state of a complex object at a certain moment, like a snapshot, and testing the object as it is actually the real one. right? I understand this. what I don't understand is what is the point of writing unit tests and assertions of certain cases that we fully describe in the mock object. If we set the expectations of arguments and return values on the mocking object, and we test for those exact values, the test will always pass. Please correct me. I know I am missing something here.
Mocks, Stubs or anything similar serves as a substitute for the actual implementation.
The idea of mocks is basically to test a piece of code in a isolated environment, substituting the dependencies for a fake implementation. For example, in Java, suppose we want to test the PersonService#save method:
class PersonService {
PersonDAO personDAO;
// Set when the person was created and then save to DB
public void save(Person person) {
person.setCreationDate(new Date());
personDAO.save(person);
}
}
A good aproach is creating a unit test like this:
class PersonServiceTest {
// Class under test
PersonService personService;
// Mock
PersonDAO personDAOMock;
// Mocking the dependencies of personService.
// In this case, we mock the PersonDAO. Doing this
// we don't need the DB to test the code.
// We assume that personDAO will give us an expected result
// for each test.
public void setup() {
personService.setPersonDao(personDAOMock)
}
// This test will guarantee that the creationDate is defined
public void saveShouldDefineTheCreationDate() {
// Given a person
Person person = new Person();
person.setCreationDate(null);
// When the save method is called
personService.save(person);
// Then the creation date should be present
assert person.getCreationDate() != null;
}
}
In another words, you should use mock to substitute dependencies of your code to an "actor" that can be configured to return an expected result or assert some behaviours.

Mocking an object with Moq, using Ninject when doing UnitTesting

I'm having trouble using Moq in a UnitTesting project with Ninject.
First a few lines about my solution. It contains several projects (BussinesLogic, DAL, Infrastructure...). My goal is to UnitTest the logic i'm using in BussinessLogic project.
The solution is basicly for a windows service, but i've put in the logic so it can be run standalone. I'm using Ninject and i specify weather i want to use the ProductionModule or the TestingModule (windows service uses ProductionModule, console app uses TestingModule)
I'm using a factory pattern to get ninject kernel whenever i need it inside my application.
My TestingModule inherits from NinjectModule where i override the Load() method and there i do the binding. For instance:
Bind<IStorageManager>().To<StubStorageManager>();
I have the StubStorageManager but it's empty. It contains just the declaration of methods from IStorageManager.
The thing i would like to do is (in laymans terms):
Create a unitTest where i would create a new kernel specifying the TestingModule as it's parameter. Then i would like to create a mock object (let's say a mock of IStorageManager) storageManagerMock. Some method in IStorageManager returns a messageObject so i would probably need to mock that too, couse the bussiness logic is doing something based on that messageObject. So i would like to somehow set properties to that message object and then call some businessLogic method on it, so i can see if the logic works correctly.
I hope i didn't complicate it too much.
Please bear with me, i'm completely new to mocking and dependency injection, but am willing to learn.
I doubt you really want to be using Ninject in your tests. The whole point of using ninject is that you can decouple everything. You also want to try and keep everything decoupled from the dependency container itself if possible. Pass it in if you have to, or pass in factories that create the required object and have the container pass in the factory.
I suspect you probably want to do something like this:
public void ATest(){
//create a mock StorageManager
var managerMock = new Mock<IStorageManager>();
//create a mock MessageObject to be used by business logic
var messageObjectMock = new Mock<MessageObject>();
//have the storage manager return the mock message when required
managerMock.Setup(x => x.GetMessageObject()).Returns(messageObjectMock.Object);
//set up message expectations
messageObjectMock.Setup(x => x.ThisValueExpected).Returns(10);
messageObjectMock.Setup(x => x.ThisFunctionShouldBeCalled()).Verifiable("Function not called.");
//thing to test
BusinessLogicObject blo = new BusinessLogicObject(managerMock.Object);
blo.DoTheThingImTesting();
//make sure the business logic called the expected function, or do whatever check you need...
messageObjectMock.Verify();
}

Unit-testing Prism with Service Locator?

I am building a Prism 4 app, and I use the ServiceLocator to instantiate objects. The ServiceLocator is causing unit testing problems, and that leads me to wonder whether I should go back to injecting the IoC container into each class that needs it.
Here is an example of the problem from a repository base class:
protected RepositoryBase(string filePath, Type contextType, string edmName)
{
m_Logger = ServiceLocator.Current.GetInstance<ILoggerFacade>();
// Log invocation
m_Logger.Log("RepositoryBase constructor invoked.", Category.Info, Priority.None);
// Create object context
...
// Log completion
m_Logger.Log("RepositoryBase constructor completed.", Category.Info, Priority.None);
}
I am creating unit tests for my repository, and I have discovered that the ServiceLocator doesn't work, presumably because Prism isn't initialized for my test.
Can the ServiceLocator be used in a testing context? Sould I drop it and go back to injecting the IoC container directly? Since service locators seem to be falling out of favor generally, would I be better off not using it? Thanks for your help.
You need to create a mock IServiceLocator, initialize the service locator with your mock provider in your test.
That should do it.
I was able to unit test a Prism + Silverlight 4 application successfully and can't think of any reason why you shouldn't be able to use ServiceLocator from your unit tests. You will need to ensure that prism is initialized correctly in the [TestInitialize] part of your code though.

How to use "Pex and Moles" library with Entity Framework?

This is a tough one because not too many people use Pex & Moles or so I think (even though Pex is a really great product - much better than any other unit testing tool)
I have a Data project that has a very simple model with just one entity (DBItem). I've also written a DBRepository within this project, that manipulates this EF model. Repository has a method called GetItems() that returns a list of business layer items (BLItem) and looks similar to this (simplified example):
public IList<BLItem> GetItems()
{
using (var ctx = new EFContext("name=MyWebConfigConnectionName"))
{
DateTime limit = DateTime.Today.AddDays(-10);
IList<DBItem> result = ctx.Items.Where(i => i.Changed > limit).ToList();
return result.ConvertAll(i => i.ToBusinessObject());
}
}
So now I'd like to create some unit tests for this particular method. I'm using Pex & Moles. I created my moles and stubs for my EF object context.
I would like to write parametrised unit test (I know I've first written my production code, but I had to, since I'm testing Pex & Moles) that tests that this method returns valid list of items.
This is my test class:
[PexClass]
public class RepoTest
{
[PexMethod]
public void GetItemsTest(ObjectSet<DBItem> items)
{
MEFContext.ConstructorString = (#this, name) => {
var mole = new SEFContext();
};
DBRepository repo = new DBRepository();
IList<BLItem> result = repo.GetItems();
IList<DBItem> manual = items.Where(i => i.Changed > DateTime.Today.AddDays(-10));
if (result.Count != manual.Count)
{
throw new Exception();
}
}
}
Then I run Pex Explorations for this particular parametrised unit test, but I get an error path bounds exceeded. Pex starts this test by providing null to this test method (so items = null). This is the code, that Pex is running:
[Test]
[PexGeneratedBy(typeof(RepoTest))]
[Ignore("the test state was: path bounds exceeded")]
public void DBRepository_GetTasks22301()
{
this.GetItemsTest((ObjectSet<DBItem>)null);
}
This was additional comment provided by Pex:
The test case ran too long for these inputs, and Pex stopped the analysis. Please notice: The method Oblivious.Data.Test.Repositories.TaskRepositoryTest.b__0 was called 50 times; please check that the code is not stuck in an infinite loop or recursion. Otherwise, click on 'Set MaxStack=200', and run Pex again.
Update attribute [PexMethod(MaxStack = 200)]
Question
Am I doing this the correct way or not? Should I use EFContext stub instead? Do I have to add additional attributes to test method so Moles host will be running (I'm not sure it does now). I'm running just Pex & Moles. No VS test or nUnit or anything else.
I guess I should probably set some limit to Pex how many items should it provide for this particular test method.
Moles is not designed to test the parts of your application that have external dependencies (e.g. file access, network access, database access, etc). Instead, Moles allows you to mock these parts of your app so that way you can do true unit testing on the parts that don't have external dependencies.
So I think you should just mock your EF objects and queries, e.g., by creating in-memory lists and having query methods return fake data from those lists based on whatever criteria is relevant.
I am just getting to grips with pex also ... my issues surrounded me wanting to use it with moq ;)
anyway ...
I have some methods similar to your that have the same problem. When i increased the max they went away. Presumably pex was satisfied that it had sufficiently explored the branches. I have methods where i have had to increase the timeout on the code contract validation also.
One thing that you should probably be doign though is passing in all the dependant objects as parameters ... ie dont instantiate the repo in the method but pass it in.
A general problem you have is that you are instantiating big objects in your method. I do the same in my DAL classes, but then i am not tryign to unit test them in isolation. I build up datasets and use this to test my data access code against.
I use pex on my business logic and objects.
If i were to try and test my DAL code id have to use IOC to pass the datacontext into the methods - which would then make testing possible as you can mock the data context.
You should use Entity Framework Repository Pattern: http://www.codeproject.com/KB/database/ImplRepositoryPatternEF.aspx

Using Moq callbacks correctly according to AAA

I've created a unit test that tests interactions on my ViewModel class in a Silverlight application. To be able to do this test, I'm mocking the service interface, injected to the ViewModel. I'm using Moq framework to do the mocking.
to be able to verify bounded object in the ViewModel is converted properly, I've used a callback:
[Test]
public void SaveProposal_Will_Map_Proposal_To_WebService_Parameter()
{
var vm = CreateNewCampaignViewModel();
var proposal = CreateNewProposal(1, "New Proposal");
Services.Setup(x => x.SaveProposalAsync(It.IsAny<saveProposalParam>())).Callback((saveProposalParam p) =>
{
Assert.That(p.plainProposal, Is.Not.Null);
Assert.That(p.plainProposal.POrderItem.orderItemId, Is.EqualTo(1));
Assert.That(p.plainProposal.POrderItem.orderName, Is.EqualTo("New Proposal"));
});
proposal.State = ObjectStates.Added;
vm.CurrentProposal = proposal;
vm.Save();
}
It is working fine, but if you've noticed, using this mechanism the Assert and Act part of the unit test have switched their parts (Assert comes before Acting). Is there a better way to do this, while preserving correct AAA order?
I'm not sure that you've changed the semantics of the AAA order. Consider the execution of the test. Your mocked interface will not be called until the Action invokes it. Therefore, during execution, your program still follows the Arrange, Act, and Assert flow.
The alternative would be to use Data Injection and create an interface between your CampaignViewModel and the web service that it uses. You can then create a class in your UnitTests that saves your parameter information and Assert on that class member/property rather than use Moq to create a proxy on the fly.
Moq should not be used to simulate storage or assignment. Rather, use Moq to provide dummy mechanisms and values to allow your Unit Tests to execute. If Asserting storage is a requirement, then take the time to create a class that will hold on to your values.