Mock objects introduce a good approach to do deep behavior testing of some program unit.
You just should pass mocked dependency to the tested unit and check if it works with dependency as it should do.
Let you have 2 classes A and B:
public class A
{
private B b;
public A(B b)
{
this.b = b;
}
public void DoSomething()
{
b.PerformSomeAction();
if(b.State == some special value)
{
b.PerformAnotherAction();
}
}
}
public class B
{
public BState State { get; private set; }
public void PerformSomeAction()
{
//some actions
State = some special value;
}
public void PerformAnotherAction()
{
if(State != some special value)
{
fail(); //for example throw new InvalidOperationException();
}
}
}
Imagine class B is being tested with unit test TestB.
To unit test class A we can either pass B to it's constructor (to do state based testing) or pass B's mock to it (to do behavior based testing).
Let say we have chosen the second approach (for example we can't verify A's state directly and can do it indirectly) and created unit test TestA (which doesn't contain any reference to B).
So we will introduce an interface IDependency and classes will look like:
public interface IDependency
{
void PerformSomeAction();
void PerformAnotherAction();
}
public class A
{
private IDependency d;
public A(IDependency d)
{
this.d = d;
}
public void DoSomething()
{
d.PerformSomeAction();
if(d.State == some special value)
{
d.PerformAnotherAction();
}
}
}
public class B : IDependency
{
public BState State { get; private set; }
public void PerformSomeAction()
{
//some actions
State = some special value;
}
public void PerformAnotherAction()
{
if(State != some special value)
{
fail(); //for example throw new InvalidOperationException();
}
}
}
and unit test TestB is something similar to:
[TestClass]
public class TestB
{
[TestMethod]
public void ShouldPerformAnotherActionWhenDependencyReturnsSomeSpecialValue()
{
var d = CreateDependencyMockSuchThatItReturnsSomeSpecialValue();
var a = CreateA(d.Object);
a.DoSomething();
AssertSomeActionWasPerformedForDependency(d);
}
[TestMethod]
public void ShouldNotPerformAnotherActionWhenDependencyReturnsSomeNormalValue()
{
var d = CreateDependencyMockSuchThatItReturnsSomeNormalValue();
var a = CreateA(d.Object);
a.DoSomething();
AssertSomeActionWasNotPerformedForDependency(d);
}
}
Ok. It's a happy moment for developer - everything is tested and all tests are green. Everything is good.
But!
When someone modifies logic of class B (for example modifies if(State != some special value) to if(State != another value) ) only TestB fails.
This guy fixes this test and thinks that everything goes well again.
But if you try to pass B to constructor of A A.DoSomething will fail.
The root cause of it is our mock object. It fixed old behavior of B object. When B changed its behavior mock didn't reflect it.
So, my question is how to make mock of B follow changes of behavior of B?
This is a question of viewpoint. Normally, you mock an interface, not a concrete class. In your example, B's mock is an implementation of IDependency, as is B. B's mock must change whenever the behaviour of IDependency changes, and you can ensure that by looking at all the implementations of IDependency when you change the defined behaviour of IDependency.
So, the enforcement is through 2 simple rules that ought to be followed in the code base:
When a class implements an interface, it must fulfill all defined behaviour of the interface after modification.
When you change an interface, you must adapt all implementers to fulfill the new interface.
Ideally, you have unit tests in place that test against the defined behaviour of an IDependency, which apply to both B and BMock and catch violations of these rules.
I differ from the other answer, which seems to be advocating subjecting both the real implementation and the (hand-made?) mock to a set of contract tests - which specify the behavior of the role/interface. I've never seen tests that exercise mocks - could be done though.
Normally you don't handcraft mocks - rather you use a mocking framework. So w.r.t. your example, my client tests would have inline statements as
new Mock<IDependency>().Setup(d => d.Method(params)
.Returns(expectedValue)
Your question is when the contract changes, how do I guarantee that the inline expectations in the client tests are also updated (or even flagged) with changes to the dependency?
The compiler won't help here. Nor would the tests. What you have is a lack of shared agreement between the client and the dependency. You'd have to manually find-and-replace (or use IDE tooling to locate all references to the interface method) and fix.
The way out is to NOT define a lot of fine-grained IDependency interfaces recklessly. Most problems can be solved with a minimal number of chunky roles (realized as interfaces) with clearly defined non-volatile behavior. You can attempt to minimize role-level changes. Initially this was a sticking point with me too - however discussions with interaction-test experts and practical experience have managed to win me over. If this does happen all too often, a quick retrospective as to the cause of fickle interfaces should yield better results.
Related
Are methods that return void but change the state of their arguments (ie. provide a hidden or implicit return value) generally a bad practice?
I find them difficult to mock, which suggests they are possibly a sign of a bad design.
What patterns are there for avoiding them?
A highly contrived example:
public interface IMapper
{
void Map(SourceObject source, TargetObject target);
}
public class ClassUnderTest
{
private IMapper _mapper;
public ClassUnderTest(IMapper mapper)
{
_mapper = mapper;
}
public int SomeOperation()
{
var source = new SourceObject();
var target = new TargetObject();
_mapper.Map(source, target);
return target.SomeMappedValue;
}
}
Yes to some extend.
What you describe is a typical side effect. Side effects make programs hard to understand, because the information you need to understand isn't contained in the call stack. You need additional information, i.e. what methods got called before (and in what) order.
The solution is to program without side effects. This means you don't change variables, fields or anything. Instead you would return a new version of what you normally would change.
This is a basic principle of functional programming.
Of course this way of programming has it's own challenges. Just consider I/O.
Your code whould be a lot easier to test if you do this:
public interface IMapper
{
TargetObject Map(SourceObject source);
}
public class ClassUnderTest
{
private IMapper _mapper;
public ClassUnderTest(IMapper mapper)
{
_mapper = mapper;
}
public int SomeOperation(SourceObject source )
{
var target = _mapper.Map(source, target);
return target.SomeMappedValue;
}
}
You can now test you Map opperation and SomeOperation seperatly. The problem is that you idd change the state of an object which makes it hard to provide a stub for testing. When returning the new object you are able to return a test stub of the target and test your caller method.
I've got an IoC container doing some complicated object construction when resolving some interfaces. I want to use implementations of these interfaces in my unit/integration tests. Is there anything wrong with resolving these interfaces in the tests using the IoC container or is it expected that one should build up instances manually in this situation?
When we are unit testing a class we are concerned with 'does the class do what we want it to do'.
Our starting point is a fully constructed instance; how we got there is not a unit testing question though it may be considered an integration testing question.
Say we have,
A
A(IB b, IC c)
B : IB
B(ID d)
C : IC
D : ID
Where:
IB is an interface for B,
IC is an interface for C, and
ID is an interface for D.
When unit testing A, the fact that B uses ID should be moot (if it is not then we should look at our interfaces. Having A access IB.D.xxx() is not good), all we need to do is provide A with some implementation (mocked/stubbed) of IB and IC.
As far as the unit tests for A are concerned, whether the A instance is created by hand or by a container is not important. We get the same object either way.
As long as we are passing in mocks as the first level dependencies then there is no saving when using a container over creating the object by hand. The saving only happens when we are creating object graphs using the IOC, but if we are doing this then we are into integration testing. This is not necessarily a bad thing but we need to be clear on our goals.
When unit testing the above we create unit testing for
D
C
B (passing in a mocked/stubbed ID)
A (passing in mocked/stubbed IC and IB)
When unit testing A we do not need the correct answer from D to be passed through B up to A.
All we care is that the logic in A works as expected, say, A calls IB.x() with the parameters y and z and returns the result of IB.x(). If we are checking that we get the correct answer (say, one which depends on logic in D) then we are past unit testing and into integration testing.
Bottom Line
It does not matter whether or not the unit under test was created by an IOC container or by hand as long as we are properly isolating the unit under test. If we are using the container to create an object graph then the odds are good that we are into integration testing (and/or have problems with too much coupling between classes - A calling IB.D.xxx())
Mocking for Integration Tests
Caveat: Some of this following is dependent upon the IOC container in use. When using Unity, the last registration 'wins'. I do not know that this holds true for others.
In the minimalist system under question we have
A
A (IB b)
B : IB
B is our 'leaf'. It talks to the outside world (say, reads from a network stream).
When Integration testing, we want to mock this.
For the live system, we set up the ServiceLocator using CreateContainerCore().
This includes the registration of the 'live' implementation of IB.
When executing integration tests that require a mocked version of IB we set up the container using CreateContainerWithMockedExternalDependencies() which wraps CreateContainerCore() and registering a mocked object for IB.
The code below is heavily simplified but the shape extends out to as many classes and dependencies as required. In practice, we have a base test class that aids setting up the service locator, mocking/stubbing classes, accessing the mocks for verification purposes and other house keeping (e.g.so that each test doesn't need to explicitly set the ServiceLocator provider)
[TestClass]
public class IocIntegrationSetupFixture {
[TestMethod]
public void MockedB() {
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(CreateContainerWithMockedExternalDependencies()));
var a = ServiceLocator.Current.GetInstance<A>();
Assert.AreEqual("Mocked B", a.GetMessage());
}
[TestMethod]
public void LiveB() {
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(CreateContainerCore()));
var a = ServiceLocator.Current.GetInstance<A>();
Assert.AreEqual("Live B", a.GetMessage());
}
private IUnityContainer CreateContainerCore() {
var container = new UnityContainer();
container.RegisterType<IB, B>(new ContainerControlledLifetimeManager());
return container;
}
private IUnityContainer CreateContainerWithMockedExternalDependencies() {
var container = CreateContainerCore();
var mockedB = new Mock<IB>();
mockedB.SetupGet(mk => mk.Message).Returns("Mocked B");
container.RegisterInstance<IB>(mockedB.Object);
return container;
}
public class A {
private IB _b;
public A(IB b) {
_b = b;
}
public string GetMessage() {
return _b.Message;
}
}
public interface IB {
string Message { get; }
}
private class B : IB {
public string Message {
get { return "Live B"; }
}
}
}
I'm trying to have the unit tests not rely on calling container.Resolve<T>() for their dependencies.
I'm currently using AutoFac 2.2.4, and tried xUnit.NET and NUnit, but both have this issue:
No parameterless constructor defined for this object
How do I get past this issue? Is it a particular unit testing framework that will support this, or just how said framework is configured?
Should I not be doing this? Or can I set up the test class to work with the constructor that has it's only dependency?
Here's some of the code:
public class ProductTests : BaseTest
{
readonly private IProductRepository _repo;
public ProductTests(IProductRepository r)
{
_repo = r;
}
//working unit tests here with default constructor
}
Did I choose to initialise the container wrongly in the base class constructor?
public abstract class BaseTest
{
protected BaseTest()
{
var builder = new ContainerBuilder();
builder.RegisterType<ProductRepository>().As<IProductRepository>();
builder.Build();
}
}
The initial problem is indeed due to how the testing frameworks are designed. They all require a parameterless constructor in order to instantiate test instances. And rightfully so. With these frameworks, the constructor is not to be relied on for test initialization. That is the purpose of the SetUp method. All in all, the test classes themselves are not suited for injection.
And IMO, this becomes a non-issue when you develop your tests to not depend on the container. After all, each test class should focus on one "system under test" (SUT). Why not have the setup method instantiate that system directly and provide each dependency (usually in the form of fakes)? By doing it this way you have effectively removed another unnecessary dependency from your tests, namely the IoC framework.
On a side note: the only time I involve the IoC framework in my tests is in my "container tests". These tests focus on verifying that certain services can be resolved from the container after the container have been initialized with application or assembly modules.
I just allow my tests to have a dependency on Autofac, although I encapsulate it. All of my TestFixtures inherit from Fixture, which is defined as such:
public class Fixture
{
private static readonly IContainer MainContainer = Ioc.Build();
private readonly TestLifetime _testLifetime = new TestLifetime(MainContainer);
[SetUp]
public void SetUp()
{
_testLifetime.SetUp();
}
[TearDown]
public void TearDown()
{
_testLifetime.TearDown();
}
protected TService Resolve<TService>()
{
return _testLifetime.Resolve<TService>();
}
protected void Override(Action<ContainerBuilder> configurationAction)
{
_testLifetime.Override(configurationAction);
}
}
public class TestLifetime
{
private readonly IContainer _mainContainer;
private bool _canOverride;
private ILifetimeScope _testScope;
public TestLifetime(IContainer mainContainer)
{
_mainContainer = mainContainer;
}
public void SetUp()
{
_testScope = _mainContainer.BeginLifetimeScope();
_canOverride = true;
}
public void TearDown()
{
_testScope.Dispose();
_testScope = null;
}
public TService Resolve<TService>()
{
_canOverride = false;
return _testScope.Resolve<TService>();
}
public void Override(Action<ContainerBuilder> configurationAction)
{
_testScope.Dispose();
if (!_canOverride)
throw new InvalidOperationException("Override can only be called once per test and must be before any calls to Resolve.");
_canOverride = false;
_testScope = _mainContainer.BeginLifetimeScope(configurationAction);
}
}
Let's say we are testing a class C which has 2 methods M1 and M2 where M1 calls M2 when executed.
Testing M2 is ok, but how can we test M1? The difficulty is that we need to mock M2 if I'm not misunderstanding things.
If so, how can we mock another method while testing a method defined in the same class?
[Edit]
Class C has no base classes.
You can do this by setting the CallBase property on the mock to true.
For example, if I have this class:
public class Foo
{
public virtual string MethodA()
{
return "A";
}
public virtual string MethodB()
{
return MethodA() + "B";
}
}
I can setup MethodA and call MethodB:
[Fact]
public void RunTest()
{
Mock<Foo> mockFoo = new Mock<Foo>();
mockFoo.Setup(x => x.MethodA()).Returns("Mock");
mockFoo.CallBase = true;
string result = mockFoo.Object.MethodB();
Assert.Equal("MockB", result);
}
You should let the call to M1 pass through to a real instance of the M2 method.
In general, you should be testing the black box behaviour of your classes. Your tests shouldn't care that M1 happens to call M2 - this is an implementation detail.
This isn't the same as mocking external dependencies (which you should do)...
For example, say I have a class like this:
class AccountMerger
{
public AccountMerger(IAccountDao dao)
{
this.dao = dao;
}
public void Merge(Account first, Account second, MergeStrategy strategy)
{
// merge logic goes here...
// [...]
dao.Save(first);
dao.Save(second);
}
public void Merge(Account first, Account second)
{
Merge(first, second, MergeStrategy.Default);
}
private readonly IAccountDao dao;
}
I want my tests to show that:
Calling Merge(first, second, strategy) results in two accounts getting saved that have been merged using the supplied rule.
Calling Merge(first, second) results in two accounts getting saved that have been merged using the default rule.
Note that both of these requirements are phrased in terms of inputs and effects - in particular, I don't care how the class achieves these results, as long as it does.
The fact that the second method happens to use the first isn't something I care about, or even that I want to enforce - if I do so, I'll write very brittle tests. (There's even an argument that if you've messed about with the object under test using a mocking framework, you're not even testing the original object any more, so what are you testing?) This is an internal dependency that could quite happily change without breaking the requirements:
// ...
// refactored AccountMerger methods
// these still work, and still fulfil the two requirements above
public void Merge(Account first, Account second, MergeStrategy strategy)
{
MergeAndSave(first, second, strategy ?? MergeStrategy.Default);
}
public void Merge(Account first, Account second)
{
// note this no longer calls the other Merge() method
MergeAndSave(first, second, MergeStrategy.Default);
}
private void MergeAndSave(Account first, Account second, MergeStrategy strategy)
{
// merge logic goes here...
// [...]
dao.Save(first);
dao.Save(second);
}
// ...
As long as my tests only check inputs and effects, I can easily make this kind of refactoring - my tests will even help me to do so, as they make sure I haven't broken the class while making changes.
On the other hand, I do about the AccountMerger using the IAccountDao to save accounts following a merge (although the AccountMerger shouldn't care about the implementation of the DAO, only that it has a Save() method.) This DAO is a prime candidate for mocking - an external dependency of the AccountMerger class, feeling an effect I want to check for certain inputs.
You shouldn't mock methods in the target class, you should only mock external dependencies.
If it seems to make sense to mock M2 while testing M1 it often means that your class is doing too many things. Consider splitting the class and keeping M2 in one class and move M1 to a higher level class, which would use the class containing M2. Then mocking M2 is easy, and your code will actually become better.
Here is my situation:
I want to test on the "HasSomething()" function, which is in the following class:
public class Something
{
private object _thing;
public virtual bool HasSomething()
{
if (HasSomething(_thing))
return true;
return false;
}
public virtual bool HasSomething(object thing)
{
....some algo here to check on the object...
return true;
}
}
So, i write my test to be like this:
public void HasSomethingTest1()
{
MockRepository mocks = new MockRepository();
Something target = mocks.DynamicMock(typeof(Something)) as Something;
Expect.Call(target.HasSomething(new Object())).IgnoreArguments().Return(true);
bool expected = true;
bool actual;
actual = target.HasSomething();
Assert.AreEqual(expected, actual);
}
Is my test written correctly?
Please help me as i can't even get the result as expected. the "HasSomething(object)" just can't be mock in that way. it did not return me 'true' as being set in expectation.
Thanks.
In response to OP's 'answer': Your main problem is that RhinoMocks does not mock members of classes - instead it creates mock classes and we can then set expectations and canned responses for its members (i.e. Properties and Functions). If you attempt to test a member function of a mock/stub class, you run the risk of testing the mocking framework rather than your implementation.
For the particular scenario of the logical path being dependent on the return value of a local (usually private) function, you really need an external dependency (another object) which would affect the return value that you require from that local function. For your code snippet above, I would write the test as follows:
[Test]
public void TestHasSomething()
{
// here I am assuming that _thing is being injected in via the constructor
// you could also do it via a property setter or a function
var sut = new Something(new object());
Assert.IsTrue(sut.HasSomething);
}
i.e. no mocking required.
This is one point of misunderstanding that I often had in the past with regards to mocking; we mock the behaviour of a dependency of the system under test (SUT). Something like: the SUT calls several methods of the dependency and the mocking process provides canned responses (rather than going to the database, etc) to guide the way the logic flows.
A simple example would be as follows (note that I have used RhinoMocks AAA syntax for this test. As an aside, I notice that the syntax that you are using in your code sample is using the Record-Replay paradigm, except that it isn't using Record and Replay! That would probably cause problems as well):
public class SUT
{
Dependency _depend
public SUT (Dependency depend)
{
_depend = depend;
}
...
public int MethodUnderTest()
{
if (_depend.IsReady)
return 1;
else
return -1;
}
}
...
[Test]
public void TestSUT_MethodUnderTest()
{
var dependency = MockRepository.GenerateMock<Dependency>();
dependency.Stub(d => d.IsReady).Return(true);
var sut = new SUT(dependency);
Assert.AreEqual(1, sut.MethodUnderTest());
}
And so the problem that you have is that you are attempting to test the behaviour of a mocked object. Which means that you aren't actually testing your class at all!
In a case like this, your test double should be a derived version of class Something. Then you override the method HasSomething(object) and ensure that HasSomething() calls your one.
If I understand correctly, you are actually interested in testing the method HasDynamicFlow (not depicted in your example above) without concerning yourself with the algorithm for HasSomething.
Preet is right in that you could simply subclass Something and override the behavior of HasSomething to short-circuit the algorithm, but that would require creating some additional test-dummy code which Rhino is efficient at eliminating.
Consider using a Partial Mock Stub instead of a Dynamic Mock. A stub is less strict and is ideal for working with Properties. Methods however require some extra effort.
[Test]
public void CanStubMethod()
{
Foo foo = MockRepository.GenerateStub<Foo>();
foo.Expect(f => f.HasDynamicFlow()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
foo.Expect(f => f.HasSomething(null)).IgnoreArguments().Return(true);
Assert.IsTrue(foo.HasDynamicFlow());
}
EDIT: added code example and switched Partial Mock to Stub