Consider this code:
private readonly Dictionary<Type, Component> _components = new Dictionary<Type, Component>();
public Component this [Type type]
{
get
{
Component component;
_components.TryGetValue(type, out component);
return component;
}
}
public void AddComponent(Component component)
{
_components.Add(component.GetType(), component);
}
As you can see, AddComponent
adds to the private _components
variable. But the only way to test this is happening is by using the indexer. That's fine, but in order to test the indexer I'd have to call AddComponent
too!
In other words, in the unit tests for the indexer and AddComponent
, each test would have to call both of these methods. It seems like this is creating unnecessary coupling. If there is a bug in the indexer, there is no reason for my TestAddComponent
to fail.
What is the best practice here? Do I use reflection to get at _components
? Mocking? Something else?
In my opinion, unit tests shouldn't do reflection to force it's goals. I think that in this kind of test, both should be tested toghether, in the same test. But that is just a point of view.
However, you can make multiple tests, changing the order of the instructions. Try to add multiple, and the access the first, then the last, then one from the middle. Each test, is one scenario, with different order, number of insertions. You can even test exceptional states that must happen... for example, if you try to get something that was not inserted.
I think that unit test exists to mimic usage, or to enforce specification. Not to see if every single bit of the program is right, because that kills flexibility.
Well you have 2 options:
As you can probably tell from the wording, my choice would be with #2 - You should test the exposed behaviour. In your case the exposed behaviour that you are testing is:
AddComponent
then the added component should be accessible through the indexerAddComponent
In this case its fairly obvious that these are pretty much the same thing, so we only really have one unit case / exposed behaviour to test here. Yes this unit test covers two different things, but that shouldn't really matter - we aren't trying to test that each method / property behaves as expected, rather we want to test that each exposed behaviour works as expected.
As an alternative, suppose that we go for option 1 and used private reflection to check the state of _components
ourselves. In this case the bevahour that we are actually testing is:
AddComponent
then the added component should be added to _components
_components
Not only are we now testing the internal behaviour of the class (so that if the implementation changes the tests fail, even if the class is working as expected), but we have just doubled the number of tests we are writing.
On top of that, by increasing the complexity of our tests we are increasing the chance that the tests themselves have a bug - for example what if we made a mistake and in test 2. we checked some completely different private field? In this case not only have we made more work for ourselves, but we aren't even testing the actual behaviour that we want to test!
When you're using Microsoft Unit Test Framework, the framework generates a private accessor class. This should allow you to access your private types. Take a look at this page from Microsoft for more info:
http://msdn.microsoft.com/en-us/library/dd293546.aspx
Specially this section: Create unit tests that can access internal, private, and friend methods.
May I suggest using interfaces and or virtual methods and MOQ. That way you can MOQ the calls to the methods you are not wanting to test and make them return what you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With