With reference to the Managed Extensibility Framework (MEF), I'm trying to work out how to create clean tests with mocks.
I have an exported component which has three private imports. Each imported object (field) needs to be mocked. Given that the CompositionContainer uses fancy reflection tactics to set imported private fields of composable parts, even in unit tests I will need to use the container to set those field values.
How do I tell the container at run time to accept a dynamic object I've created with Rhino Mocks as a valid export so that it can be used to satisfy the imports in the component I'm testing?
My question has been answered here.
Hi Nathan
There's a couple of different options here.
Using a batch, you can call the AddExportedObject method to add a mock instance to the container. AddExportedObject allows you to specify the contract for the instance that you are adding. i.e. batch.AddExportedObject(mockLogger, typeof(ILogger));
You an also create a custom export provider to allow you add mock instances. If you follow this link, here are some utils that I use. http://pastie.org/467842. Within you'll find a FakeExportProvider, along with FakeExportDefinitions. The FakeExportDefinitions take a func for the instance. This means you can pass it an instance, or even directly create a mock.
Here's sample code to illustrate usage.
protected override void Context()
{
MockCache = MockRepository.GenerateStub<ICache>();
var metadata = new Dictionary<string, object> ()
var cacheDefinition = new FakeInstanceExportDefinition(typeof(ICache), MockCache, metadata);
FakeProvider = new FakeExportProvider(f => ((FakeInstanceExportDefinition)f).Instance);
FakeProvider.AddExportDefinitions(cacheDefinition);
CacheExport = FakeProvider.GetExport<ICache>();
}
Now above I am querying the export provider directly. However, our container allows passing in an export provider in it's construction. So you can do this...
var container = new CompositionContainer(null, FakeProvider).
HTH
Glenn
Related
could not able to create a mock for
public MetricsProvider(IConfig configData, IMetricsLogger log)
{
config = configData;
logger = log;
oracleDAL = new OracleDataAccess(config, logger);
MetricsData = new DataCollector();
}
Steps I did:
Creatde a mock object for IConfig and IMetricsLogger.
I tried to call MetricsProvider (config , logger) but its referring Oracle connection and could not able to get connection or mock connection object.
This is actually a perfect example of why dependency injection is beneficial.
What you want is to test MetricsProvider. But because MetricsProvider internally creates an instance of OracleDataAccess and DataCollector you can't test MetricsProvider without testing those classes also.
But what do those classes depend on? Do they require additional dependencies, like app.config settings that can't be seen without looking at the source code for those classes? (And what if those classes have dependencies on other classes that have more dependencies?)
And if your test fails it will be difficult to tell if the defect is in MetricsProvider or some unknown dependency hidden in some other class.
The way to fix it is to pass an interface to the constructor which is implemented by OracleDataAccess. If it that class doesn't already implement an interface you could create a new one corresponding to the existing class. Or if you only need one method, you could define a more specific interface and wrap OracleDataAccess in a class that implements that interface.
Then MetricsProvider will depend on an interface injected into the constructor which you'll be able to mock. Since that mock will enable you to determine exactly how IOracleDataAccess behaves, now you'll be able to test MetricsProvider in isolation.
I'm trying to create a unit test for an ASP.NET that has the following constructor definition (filled with Ninject when running the real application):
public OrderController(IViewModelFactory modelFactory, INewsRepository repository, ILoggedUserHelper loggedUserHelper,
IDelegateHelper delegateHelper, ICustomerContextWrapper customerContext) {
this.factory = modelFactory;
this.loggedUserHelper = loggedUserHelper;
this.delegateHelper = delegateHelper;
this.customerContext = customerContext;
}
I want to test the methods inside the OrderController class, but in order to isolate it, I have to mock all and every of those dependencies, which becomes outright ridiculous (having to also mock subdependencies probably).
In this case, which is the best practice to Unit Test this class?
Well, you have to provide test doubles for all dependencies, not necessarily mocks.
Luckily,this is the 21st century and there are tools to make the job easier for us. You can use AutoFixture to create an instance of OrderController and inject mocks as necessary.
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var orderController = fixture.Create<OrderController>();
Which, basically, is equivalent to:
var factory = new Mock<IViewModelFactory>();
var repository = new Mock<INewsRepository>();
var delegateHelper = new Mock<IDelegateHelper >();
var customerContext = new Mock<ICustomerContextWrapper >();
var orderController = new OrderController(factory.Object, repository.Object, delegateHelper.Object, customerContext.Object);
If those dependencies depend on other types, those will be setup as well. AutoFixture with the AutoConfiguredMoqCustomization customization will build an entire graph of dependencies.
If you need access to, say, the repository mock, so you can do some additional setups or assertions on it later, you can freeze it. Freezing a type will make the fixture container contain only one instance of that type, e.g.:
var fixture = new Fixture().Customize(new AutoConfiguredMoqCustomization());
var repositoryMock = fixture.Freeze<Mock<INewsRepository>>();
repositoryMock.Setup(x => x.Retrieve()).Returns(1);
//the frozen instance will be injected here
var orderController = fixture.Create<OrderController>();
repositoryMock.Verify(x => x.Retrieve(), Times.Once);
I've used Moq in these examples, but AutoFixture also integrates with NSubstitute, RhinoMock and Foq.
Disclosure: I'm one of the project's contributors
No, you don't. The different concepts of test object implementations you can use are known as Test Doubles. Mocks are just one type of Test Double as defined by Gerard Meszaros in his book:
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.
You only need to give as many stubs, fakes and dummies as required for your test to pass.
Dummies take very little work to generate and may be enough to cover your scenario. An example would be a constructor that takes an IEmailer and an ILogWriter. If you're only testing the Log method, you only need to provide enough of an implementation of IEmailer in order for the test to not throw Argument exceptions.
Also, regarding your point about sub-dependencies... Moq will take care of that for you, because Moq implementations of your interface won't take dependencies.
I've been trying to shift myself into a more test driven methodology when writing my .net MVC based app. I'm doing all my dependency injection using constructor-based injection. Thus far it's going well, but I've found myself doing something repeatedly and I'm wondering if there is a better practice out there.
Let's say I want to test a Controller. It has a dependency on a Unit Of Work (database) object. Simple enough... I write my controller to take that interface in its constructor, and my DI framework (Ninject) can inject it at runtime. Easy. Meanwhile in my unit test, I can manually construct my controller with a mocked-up database object. I like that I can write lots of individual self-contained tests that take care of all the object construction and testing.
Now I've moved on and started adding new features & functions to my Controller object. The Controller now has one or two more dependencies. I can write more tests using these 3 dependencies, but my older tests are all broken (won't compile), as the compiler throws a whole bunch of errors like this:
'MyProject.Web.Api.Controllers.MyExampleController' does not contain a constructor that takes 3 arguments
What I've been doing (which smells bad) is going back and updating all my unit tests, changing the construction code, and adding null parameters for all the new dependencies that my old tests don't care about, like this:
From this:
var controllerToTest = new MyExampleController(mockUOW.Object);
To this:
var controllerToTest = new MyExampleController(mockUOW.Object, null, null);
This gets everything to compile and gets my tests to run again, but I don't like the prospect of going back and editing tons of old tests just to change calls to my object constructors.
Is there a better way to write your unit tests (or a better way to write your classes and do DI?) so they don't all break when you add a new dependency?
You've run into a common issue when unit testing: duplication of code causing significant refactoring overhead. The solution is to try to restrict the instantiation of the object(s) under test to a single place. If you can, try to do it in the TestInitialize method of your tests:
[TestInitialize]
public void Init()
{
this.mockUOW = new Mock<ISomeDependency>();
this.mock2 = new Mock<IAnotherDependency>();
this.mock3 = new Mock<IYetAnotherDependency>();
// Do initial set-up on your mocks
this.controllerToTest = new MyExampleController(this.mockUOW, this.mock2, this.mock3);
}
Sometimes, this isn't practical: you need to do specific set-up in each test before you create an instance of the class under test. In this situation, move the code to create the object into a well-named method, and call that:
[TestMethod]
public void MyTestMethod()
{
// Do any required set-up on mocks, etc.
this.CreateController();
}
private void CreateController()
{
this.controllerToTest = new MyExampleController(this.mockUOW, this.mock2, this.mock3);
}
Now you (hopefully) have only a single place in your tests to update when dependencies get added to one of your controllers.
Note also that that the CreateController method isn't named CreateMyExampleController. As a best practice, I try to avoid method names in tests that are specific to certain classes or methods. Here, for example, including the class name in the method adds another refactoring dependency which is easily overlooked.
You just inline the mock initialization. Instead of supplying null just supply new Mock<IClassName>.Object().
You can try using automock (on codeplex) to automatically mock out your top-level objects, this reduces the amount of retyping that you need to fix objects.
Tests should not share the same context - you should be trying to test a stateless system. For the most part without refactoring tools enabled you're just going to have to deal with it.
Resharper is very powerful in this regard. When you add a new class, you can Ctrl+F6 and add a new parameter to a constructor. It will prompt you with how to fill caller locations - just type your mock in there and everywhere that it matters (if you are injecting all your dependencies the right way) will be filled in automatically.
If your DI container supports multiple instances (i.e. Unity does) you can use local container to resolve all references instead of calling constructor.
Pseudocode:
var container = new MyDependencyContainer();
container.RegisterInstance<IMyInterface>(mockedMyInterface);
var myClass = container.Reslove(myClass);
To simplify code in each test you can have container/mocks as field and configure container in method marked with [TestInitialize] attribute.
Note that such code will not break at compile time when you add dependency to constructor, but likely still require changes (i.e. adding new dependencies to container).
I currently have a repository that is using Entity Framework for my CRUD operations.
This is injected into my service that needs to use this repo.
Using AutoMapper, I project the entity Model onto a Poco model and the poco gets returned by the service.
If my objects have multiple properties, what is a correct way to set-up and then assert my properties?
If my service has multiple repo dependencies what is the correct way to setup all my mocks? * - A class [setup] where all the mocks and objects are configured for these test fixtures?*****
I want to avoid having 10 tests and each test has 50 asserts on properties and dozens on mocks set-up for each test. This makes maintainability and readability difficult.
I have read Art of Unit Testing and did not discover any suggestions how to handle this case.
The tooling I am using is Rhino Mocks and NUnit.
I also found this on SO but it doesn't answer my question: Correctly Unit Test Service / Repository Interaction
Here is a sample that expresses what I am describing:
public void Save_ReturnSavedDocument()
{
//Simulate DB object
var repoResult = new EntityModel.Document()
{
DocumentId = 2,
Message = "TestMessage1",
Name = "Name1",
Email = "Email1",
Comment = "Comment1"
};
//Create mocks of Repo Methods - Might have many dependencies
var documentRepository = MockRepository.GenerateStub<IDocumentRepository>();
documentRepository.Stub(m => m.Get()).IgnoreArguments().Return(new List<EntityModel.Document>()
{
repoResult
}.AsQueryable());
documentRepository.Stub(a => a.Save(null, null)).IgnoreArguments().Return(repoResult);
//instantiate service and inject repo
var documentService = new DocumentService(documentRepository);
var savedDocument = documentService.Save(new Models.Document()
{
ID = 0,
DocumentTypeId = 1,
Message = "TestMessage1"
});
//Assert that properties are correctly mapped after save
Assert.AreEqual(repoResult.Message, savedDocument.Message);
Assert.AreEqual(repoResult.DocumentId, savedDocument.DocumentId);
Assert.AreEqual(repoResult.Name, savedDocument.Name);
Assert.AreEqual(repoResult.Email, savedDocument.Email);
Assert.AreEqual(repoResult.Comment, savedDocument.Comment);
//Many More properties here
}
First of all, each test should only have one assertion (unless the other validates the real one) e.q. if you want to assert that all elements of a list are distinct, you may want to assert first that the list is not empty. Otherwise you may get a false positive. In other cases there should only be one assert for each test. Why? If the test fails, it's name tells you exactly what is wrong. If you have multiple asserts and the first one fails you don't know if the rest was ok. All you know than is "something went wrong".
You say you don't want to setup all mocks/stubs in 10 tests. This is why most frameworks offer you a Setup method which runs before each test. This is where you can put most of your mocks configuration in one place and reuse it. In NUnit you just create a method and decorate it with a [SetUp] attribute.
If you want to test a method with different values of a parameter you can use NUnit's [TestCase] attributes. This is very elegant and you don't have to create multiple identical tests.
Now lets talk about the useful tools.
AutoFixture this is an amazing and very powerful tool that allows you to create an object of a class which requires multiple dependencies. It setups the dependencies with dummy mocks automatically, and allows you to manually setup only the ones you need in a particular test. Say you need to create a mock for UnitOfWork which takes 10 repositories as dependencies. In your test you only need to setup one of them. Autofixture allows you to create that UnitOfWork, setup that one particular repository mock (or more if you need). The rest of the dependencies will be set up automatically with dummy mocks. This saves you a huge amount of useless code. It is a little bit like an IOC container for your test.
It can also generate fake objects with random data for you. So e.q. the whole initialization of EntityModel.Document would be just one line
var repoResult = _fixture.Create<EntityModel.Document>();
Especially take a look at:
Create
Freeze
AutoMockCustomization
Here you will find my answer explaining how to use AutoFixture.
SemanticComparison Tutorial This is what will help you to avoid multiple assertions while comparing properties of objects of different types. If the properties have the same names it will to it almost automatically. If not, you can define the mappings. It will also tell you exactly which properties do not match and show their values.
Fluent assertions This just provides you a nicer way to assert stuff.
Instead of
Assert.AreEqual(repoResult.Message, savedDocument.Message);
You can do
repoResult.Message.Should().Be(savedDocument.Message);
To sum up. These tools will help you create your test with much less code and will make them much more readable. It takes time to get to know them well. Especially AutoFixture, but when you do, they become first things you add to your test projects - believe me :). Btw, they are all available from Nuget.
One more tip. If you have problems with testing a class it usually indicates a bad architecture. The solution usually is to extract smaller classes from the problematic class. (Single Responsibility Principal) Than you can easily test the small classes for business logic. And easily test the original class for interactions with them.
Consider using anonymous types:
public void Save_ReturnSavedDocument()
{
// (unmodified code)...
//Assert that properties are correctly mapped after save
Assert.AreEqual(
new
{
repoResult.Message,
repoResult.DocumentId,
repoResult.Name,
repoResult.Email,
repoResult.Comment,
},
new
{
savedDocument.Message,
savedDocument.DocumentId,
savedDocument.Name,
savedDocument.Email,
savedDocument.Comment,
});
}
There is one thing to look-out for: nullable types (eg. int?) and properties that might have slightly different types (float vs double) - but you can workaround this by casting properties to specific types (eg. (int?)repoResult.DocumentId ).
Another option would be to create a custom assert class/method(s).
Basically, the trick is to push as much clutter as you can outside of the unittests, so that only the behaviour
that is to be tested remains.
Some ways to do that:
Don't declare instances of your model/poco classes inside each test, but rather use a static TestData class that
exposes these instances as properties. Usually these instances are useful for more than one test as well.
For added robustness, have the properties on the TestData class create and return a new object instance every time
they're accessed, so that one unittest cannot affect the next by modifying the testdata.
On your testclass, declare a helper method that accepts the (usually mocked) repositories and returns the
system-under-test (or "SUT", i.e. your service). This is mainly useful in situations where configuring the SUT
takes more than 2 or more statements, since it tidies up your test code.
As an alternative to 2, have your testclass expose properties for each of the mocked Repositories, so that you don't need to declare these in your unittests; you can even pre-initialize them with a default behaviour to reduce the configuration per unittest even further.
The helper method that returns the SUT then doesn't take the mocked Repositories as arguments, but rather contstructs the SUT using the properties. You might want to reinitialize each Repository property on each [TestInitialize].
To reduce the clutter for comparing each property of your Poco with the corresponding property on the Model object, declare a helper method on your test class that does this for you (i.e. void AssertPocoEqualsModel(Poco p, Model m)). Again, this removes some clutter and you get the reusability for free.
Or, as an alternative to 4, don't compare all properties in every unittest, but rather test the mapping code in only one place with a separate set of unittests. This has the added benefit that, should the mapping ever include new properties or change
in any other way, you don't have to update 100-odd unittests.
When not testing the property mappings, you should just verify that the SUT returns the correct object instances (i.e. based on Id or Name), and that just the properties that might be changed (by the business logic being currently tested)
contain the correct values (such as Order total).
Personally, I prefer 5 because of its maintainability, but this isn't always possible and then 4 is usually a viable alternative.
Your test code would then look like this (unverified, just for demonstration purposes):
[TestClass]
public class DocumentServiceTest
{
private IDocumentRepository DocumentRepositoryMock { get; set; }
[TestInitialize]
public void Initialize()
{
DocumentRepositoryMock = MockRepository.GenerateStub<IDocumentRepository>();
}
[TestMethod]
public void Save_ReturnSavedDocument()
{
//Arrange
var repoResult = TestData.AcmeDocumentEntity;
DocumentRepositoryMock
.Stub(m => m.Get())
.IgnoreArguments()
.Return(new List<EntityModel.Document>() { repoResult }.AsQueryable());
DocumentRepositoryMock
.Stub(a => a.Save(null, null))
.IgnoreArguments()
.Return(repoResult);
//Act
var documentService = CreateDocumentService();
var savedDocument = documentService.Save(TestData.AcmeDocumentModel);
//Assert that properties are correctly mapped after save
AssertEntityEqualsModel(repoResult, savedDocument);
}
//Helpers
private DocumentService CreateDocumentService()
{
return new DocumentService(DocumentRepositoryMock);
}
private void AssertEntityEqualsModel(EntityModel.Document entityDoc, Models.Document modelDoc)
{
Assert.AreEqual(entityDoc.Message, modelDoc.Message);
Assert.AreEqual(entityDoc.DocumentId, modelDoc.DocumentId);
//...
}
}
public static class TestData
{
public static EntityModel.Document AcmeDocumentEntity
{
get
{
//Note that a new instance is returned on each invocation:
return new EntityModel.Document()
{
DocumentId = 2,
Message = "TestMessage1",
//...
}
};
}
public static Models.Document AcmeDocumentModel
{
get { /* etc. */ }
}
}
In general, if your having a hard time creating a concise test, your testing the wrong thing or the code your testing has to many responsibilities. (In my experience)
In specific, it looks like your testing the wrong thing here. If your repo is using entity framework, your getting the same object back that your sending in. Ef just updates to Id for new objects and any time stamp fields you might have.
Also, if you can't get one of your asserts to fail without a second assert failing, then you don't need one of them. Is it really possible for "name" to come back ok but for "email" to fail? If so, they should be in separate tests.
Finally, trying to do some tdd might help. Comment out all the could in your service.save. Then, write a test that fails. Then un comment out only enough code to make your test pass. Them write your next failing test. Can't write a test that fails? Then your done.
Here is my code below. I am using the Moq library. Instead of letting Moq create an instance for me. I need to flat into a type to pass to someone to create instance later. How do I do that?
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.Bar()).Returns(true);
// Test the actual method
DoSomething(mockedIStateProvider.Object.GetType());
// Not my code, it's a 3rd party library, not allowed to change
public void DoSomething(Type type)
{
Activator.CreateInstance(type);
...
...
}
You can't with Moq. The Activator will always create a new instance which you won't have access to so you won't be able to setup the mocking behaviour you want.
That being said, you can probably get the behaviour you want by writing your own stub implementation that will always do what you want.