I am using AutoData with AutoMoqCustomization (the InlineAutoMockData attribute sets this up for me) to auto-inject constructor parameters for my SUT. One particular SUT has some business logic that happens in a constructor which requires the mocked & frozen injected dependencies to be set up prior to the constructor executing. My workaround right now is as follows (using Moq + NUnit3 + Autofixture):
[Test,
InlineAutoMockData(DbPermissionsMode.ElevatedDefault, true),
InlineAutoMockData(DbPermissionsMode.ReducedNoViewServerState, false)]
public void Enumerator_mappings_are_correct(
DbPermissionsMode permissionMode, bool expectedBool,
[Frozen] Mock<IProductConfigProvider> configProvider,
IFixture fixture)
{
configProvider.Setup(x => x.GetDatabasePermissionsMode(It.IsAny<bool>()))
.Returns(permissionMode);
var vm = fixture.Build<CredentialsControlViewModel>()
.OmitAutoProperties()
.Create();
vm.UseElevatedPermissions.Should().Be(expectedBool);
}
In this test, CredentialsControlViewModel invokes IProductConfigProvider.GetDatabasePermissionsMode() in its constructor. This workaround allows me to perform setup on the configProvider mock instance prior to constructing the vm variable using the injected fixture.
What would be more ideal to clean this up is something like this, which in my mind should be functionally the same:
[Test,
InlineAutoMockData(DbPermissionsMode.ElevatedDefault, true),
InlineAutoMockData(DbPermissionsMode.ReducedNoViewServerState, false)]
public void Enumerator_mappings_are_correct(
DbPermissionsMode permissionMode, bool expectedBool,
[Frozen] Mock<IProductConfigProvider> configProvider,
[NoAutoProperties] Lazy<CredentialsControlViewModel> vm)
{
configProvider.Setup(x => x.GetDatabasePermissionsMode(It.IsAny<bool>()))
.Returns(permissionMode);
vm.Value.UseElevatedPermissions.Should().Be(expectedBool);
}
Here, I no longer use the IFixture directly. Instead, I want Lazy<> to behave as follows:
Internally create the given type (CredentialsControlViewModel) exactly as it would have been created if I instead passed in the parameter to the test as CredentialsControlViewModel vm (i.e. do it through Autofixture).
Propagate all of the attributes attached to Lazy<> to the type created by Lazy's factory function (append all of the customizations / specimen builders)
In all reasonable aspects, act as if I had done [NoAutoProperties] CredentialsControlViewModel vm directly, just within a factory function provided to Lazy<> instead of done immediately.
As a pseudo-code analogy, I would expect it to set up a Lazy<> from my earlier example like this:
var fixture = new Fixture().Customize(new AutoMoqCustomization { ConfigureMembers = true });
var lazy = new Lazy<CredentialsControlViewModel>(() =>
{
return fixture.Create<CredentialsControlViewModel>();
});
I see that there's already a LazyRelay, but it doesn't do this, I think. I believe it just forwards the factory functionality to Func<>, but I still get a MissingMemberException from Lazy because there is no default constructor. This blog post says that this should work, so I'm not sure what is going on.
I am happy to customize this if needed, I just don't know how to do that properly. AutoFixture customizations have a steep learning curve.
Could someone recommend a way to customize AutoFixture to get this behavior for Lazy? Note that I want this solution to be generic. I don't want to have to do a fixture.Register() for every closed type of Lazy<>.
Related
Disclaimer - this is not the same question as How to use FakeItEasy to assert a method was not called
Explanation
I have a piece of code which registers stuff with an IOC container, and I can use FakeItEasy in my tests to ensure that registrations are made.
I am trying to work out how to ensure that unexpected calls are not made.
Quick repo (problem boiled down to a couple of test classes - this is not a real implementation)
public class Foo
{
private readonly ICustomContainer m_CustomContainer;
public Foo(ICustomContainer customContainer)
{
m_CustomContainer = customContainer;
}
public void Bar()
{
m_CustomContainer.Register<IMyInterface, IMyImplementation>();
}
}
public interface ICustomContainer
{
void Register<TInterface, TImplementation>() where TImplementation : TInterface;
}
public class UnitTest1
{
[Fact]
public void Test1()
{
//Arrange
ICustomContainer fake = A.Fake<ICustomContainer>();
Foo objectUnderTest = new Foo(fake);
//Act
objectUnderTest.Bar();
//Assert
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
//A.CallTo(() => fake.Register<???>()).MustNotHaveHappened(); //Any generic parameter apart from <IMyInterface, IMyImplementation> must not have happened
}
}
The above test will pass - which is correct. If in the future I was to add another registration in the Bar(), it would still pass - which isn't so good as my test is only testing known scenarios.
What I am trying to achieve
So, given the interface defined above for ICustomContainer which is my IOC container, I would like to ensure that it is called only as expected.
What I have already investigated
Having used other mocking frameworks in the past such as TypeMock Isolator, I could set the fake object up to throw exceptions unless specific (expected) calls are made. I don't know if I can do this with FakeItEasy. Also TypeMock Isolator doesn't support .NET Core, so it is no good to me.
If I had a method that didn't use a generic parameter, I could get FakeItEasy to count the number of times that the method had been invoked, and expect that it had been invoked with any arguments in addition to testing the expected calls. That is certainly an option, but means that I have to create a facade over my interface (as an extension method or a wrapper, I guess) to take in type parameters rather than generic parameters, which means that I lose the pre-compile time warnings I get with the generic parameter constraint.
The actual question
How do I amend my test so that I can assert that an unexpected call was not made with any generic parameters other than those I was expecting using .NET Core / FakeItEasy / xUnit?
I may be oversimplifying, but it sounds like a Strict Fake can help you.
Make one, then explicitly allow whatever calls you want.
//Arrange
ICustomContainer fake = A.Fake<ICustomContainer>(x => x.Strict());
// allow just the registrations you want to
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).DoesNothing();
Foo objectUnderTest = new Foo(fake);
//Act
objectUnderTest.Bar();
//Assert
A.CallTo(() => fake.Register<IMyInterface, IMyImplementation>()).MustHaveHappened();
I have an interface like this
public interface IConnection
{
Strategy Gc { get; }
bool IsConnected();
bool Connect();
}
I want to unit test methods of a class that uses this interface. Now I want to set Gc but it happens to be readonly. Is there a way to set Gc field without making changes to this interface class?
I am using MS fakes and Nsubstitute for unit testing. However, apparently none provides a solution. PrivateObject does not work either.
Changing Interface is not an option. Suggest better solutions.
With NSubstituteit is quite easy. First create a mock for your interface:
var mock = Substitute.For<IConnection>();
Now you can mock the member by setting any return-type for the property:
mock.Gc.Returns(Substitute.For<Strategy>());
Finally provide that mocked instance as parameter to the service depending on that instance, for example:
var target = new MyClassToTest();
target.DoSomething(mock); // mock is an instance of IConnection
Now whenever your method is called it returns a dumm-instance for Strategy. Of course you can also set any other arbitrary return-type within the Returns-statement. Just have a look at http://nsubstitute.github.io/help/set-return-value for further information.
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 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.
I have some code similar to the following:
public interface IMyClass
{
MyEnum Value { get; }
IMyItemCollection Items { get; }
}
public class MyConcreteClassFactory : MyClassFactoryBase
{
public override IMyClass Create(MyEnum value)
{
var itemBuilder = new MyRemoteItemBuilder();
var itemCollection = new MyLazyItemCollection(itemBuilder)
return new MyClass(value, itemCollection);
}
}
The 'real' code should only care about the fact that the factory returns an instance of IMyClass - not what the concrete implementation is. Still, I would like to test that the factory class does what it is supposed to - build a concrete object graph.
Should I write some tests that call the create method and inspect the properties of the returned object? This question seems to indicate so, but does that still apply if I need to inspect several layers of classes and properties to verify the object graph created by the factory? Wouldn't that lead to test code such as:
var created = objectUnderTest.Create(MyEnum.A);
var itemBuilder = (created.Items as MyLazyItemCollection).Builder;
Assert.IsInstanceOfType(itemBuilder, typeof(MyRemoteItemBuilder));
I'm not particularly fond of the downcast of created.Items, but as I see it that would be the only way to assert that the factory created the MyLazyItemCollection correctly, since not every IMyItemCollection can be expected to have a builder property... And this is only the second layer of the graph. I might need to dig even further into the dependencies of the MyRemoteItemBuilder to see if they were created correctly:
var service = ((created.Items as MyLazyItemCollection)
.Builder as MyRemoteItemBuilder).Service;
Assert.IsInstanceOfType(service, typeof(MyService));
Should I test my factory in this manner, accepting the unsightly nested downcasts - this is test code, after all - or should I pull the IMyItemCollection construction into another factory and add this as a dependency to my MyConcreteClassFactory (so I could inject it from the test code and assert that the value of created.Items was the instance created by my mocked factory). I expect the latter would quickly lead to an explosion in factory-factories and factory-factory-factories. After all, the user of the MyConcreteClassFactory shouldn't need to be bothered with the fact that she has to supply specific sub factories, should she..?
It is of cause depends on needs, but my answer is NO.
You should never design your tests in a manner "Test implementation (or detail)", that might work really nice at the beginning, but after a while you will be in trouble. Implementation is chaning really fast, with each change you are forced to correct many test cases.
In opposite, you must "Test behaviour". It basically means you abstract of all details (concrete class) and you tests cases testing some valuable scenarios, instead of details.
My options is to create "Test implementation" cases, then I'm doind TDD. But later on they have to be refactored out with "Test behaviour" cases.
This is quite important if you case not only about count of test case, but quality in building real Safety Net.