Dependency Injection and Unit test this constructor - unit-testing

I have a constructor and a property in the class:
private IMyCollectionObjects _myCollectionObjects;
public MyClassConstructor(string message)
{
_myCollectionObjects = MyCollection.GetCollectionObejects(message);
}
With as much detail can you please help me understand how to unit test this constructor
and GetCollectionObjects method?
How do I completely decouple the
classes? You can give the answer
using any IoC, I want to
understand the concept.
Thank you.

Dependencies on static members such as GetCollectionObjects are difficult to test because you can't replace its implementation at runtime. This means that you cannot fully isolate an instance of MyClassConstructor from the implementation details of GetCollectionObjects. Without isolation of the test target, it can't really be considered a unit test.
See here for further discussion of static dependencies.
You can refactor this code to be fully decoupled (and thus fully testable):
private readonly IMyCollectionObjects _myCollectionObjects;
public MyClassConstructor(IMyCollectionObjects myCollectionObjects)
{
_myCollectionObjects = myCollectionObjects;
}
This bubbles the knowledge of how to turn a message into a collection right out of MyClassConstructor, making the class simpler, more cohesive, and less coupled.

For of all, unit testing is all about unitary testing, that is, one thing at a time.
With as much detail can you please help me understand how to unit test this constructor and GetCollectionObjects method?
First things first, have you unit tested your MyCollection class?
If not, you should begin with it, as your MyClassConstructor class depends on it, that is the basis of dependency injection. Otherwise, how can you manage to know if the results you're getting are right or wrong? You won't be able to test and be sure that it works flawlessly.
How do I completely decouple the classes? You can give the answer using any IoC, I want to understand the concept.
I my humble point of view, you must have a clear reason to make an object dependant of another using dependency injection. Once you make an object depend on another, it makes no sense, in my opinion, to decouple them. One way of decoupling might be to use Unity Application Block of Enterprise Library.
Unit test this constructor
You generally only need to check for three things while testing such a constructor.
That the constructor doesn't return a null value;
That the instance it returns is of the expected type;
That the object you expect to be instantiated through its dependency is actually instiated.
[TestCase("message")]
public void DependentConstructorTest(string message) {
MyClassConstructor myclass = new MyClassConstructor(message);
Assert.IsNotNull(myclass);
Assert.IsInstanceOf(typeof(MyClassConstructor), myclass);
Assert.IsNotNull(myclass.MyCollection); // Where MyCollection represents the property that
// exposes the instance created of the object from
// which your MyClassConstructor class depends on.
}
Note: This test is written using NUnit attributes and assertion methods. Use whatever else you like.

Here is roughly what you would need to do (with some assumptions).
Assuming MyCollection is a static class and GetCollectionObjects parses a string and returns an IMyCollectionObjects, you would first need to make MyCollection non-static, and pass it through the constructor as well. Static classes/methods used in a class create a tight coupling, more or less by definition.
Now you would be constructing the class passing a message string and a MyCollection. Your constructor uses the two in combination to populate a member variable of type IMyCollectionObjects. In order to ensure that this happens as expected, you will need a way to examine the result from outside the class (i.e. a public method). So you will need a property getter that exposes _myCollectionObjects.
Now you just need to call this contructor from one or more tests, and check the property after construction to ensure parsing the string into a collection was successful.
Note that this is really more of an integration test than a discrete unit test. You are really testing that the parsing was successful. If the class represented here is really what you intend to test, the test would really just be checking that GetCollectionObjects was called. The result of that call is really irrelevant, because you would (presumably) have a separate test or set of tests that ensure that the method GetCollectionObjects on MyCollection works as expected.

Related

Testing a unit for which a specific private method invocation is required?

I have a testing dilemma:
I'm writing a unit test for Unit A. The method I'm about to test is func(B param). In the (non testing) code the only place where the func(..) is called is in class C, it's also the only place in the project where variables of type B can be instanciated (to be sent as parameters to the func(B param), so the instanciation method is private.
Now, I'm not sure how should I create a B instance inside the Unit test.
Of cause I can change private to public in a method declaration of the method which creates B, but I don't feel right about it, since it'll expose the method to the rest of the project.
I can also simply duplicate the B creation method into the Unit test class, but I hate duplicating code.
Is there some known best practice for such cases?
Thanks a lot,
Dima
You would be looking into using a mocking framework like EasyMock or Mokito to create a "test double" object of your class B here.
As a rule of thumb, only public methods should be tested directly. By extension, public code should test all private code. Depending on what language you're using, you can also force less exposed code to be exposed to unit testing frameworks without having to change every method (e.g. InternalsVisibleTo in C#) but I accept that this option won't be available to all languages using all frameworks.
As well as unit testing, another tool in your armoury should be some sort of code coverage tool to ensure that as much of your code is being covered by said tests as possible.

Static Methods As A Wrapper

If you have a class called MyClass with a set of public methods; MethodA, MethodB and MethodC. And in some locations of an application you only need a single method from MyClass, for example:
MyClass myClass = new MyClass();
myClass.MethodA();
To simplify the above I would like to create a single static method that wraps the above lines of coded. I am planning to write unit tests against MethodA. In my unit test MethodA interacts with an interface that is implemented using a mock framework (I think this is called Inversion of Control).
Is it safe to assume that by testing MethodA that the static method (wrapper method) is also being tested indirectly. I am assuming the actually implementation for the interface used in MethodA is also being tested.
Or should I not implemented the static method?
Please, don't do that!
Static methods used like you want to do are the exact opposite of inversion of control / dependency injection, and as such, are a bad practice.
What you want to do is inject into all classes that need a MyClass an interface to it (either injected through the constructor or a setter, manually or using a IoC framework like Spring).
If you wrap your lines of code in a static method that you call from another class, then you'll couple the specific implementation of MyClass too tightly, which is the opposite of what you want to achieve.
But to answer your more specific question, it's never safe to assume the code is tested by another test, unless it actually is. What I mean is: if there is NO test that go through the static method, then it's not covered. Even if you may think it's trivial, don't forget it may be refactored later, and no test will indicate it's broken.
No, it's not safe to assume the wrapper method is also being tested. There is code in the wrapper method, and that code could have a defect in it, so you'll need to write unit tests against that code as well.

tdd - should I mock here or use real implementation

I'm writing program arguments parser, just to get better in TDD, and I stuck with the following problem. Say I have my parser defined as follows:
class ArgumentsParser {
public ArgumentsParser(ArgumentsConfiguration configuration) {
this.configuration = configuration;
}
public void parse(String[] programArguments) {
// all the stuff for parsing
}
}
and I imagine to have ArgumentsConfiguration implementation like:
class ArgumentsConfiguration {
private Map<String, Class> map = new HashMap<String, Class>();
public void addArgument(String argName, Class valueClass) {
map.add(argName, valueClass);
}
// get configured arguments methods etc.
}
This is my current stage. For now in test I use:
#Test
public void shouldResultWithOneAvailableArgument() {
ArgumentsConfiguration config = prepareSampleConfiguration();
config.addArgument("mode", Integer.class);
ArgumentsParser parser = new ArgumentsParser(configuration);
parser.parse();
// ....
}
My question is if such way is correct? I mean, is it ok to use real ArgumentsConfiguration in tests? Or should I mock it out? Default (current) implementation is quite simple (just wrapped Map), but I imagine it can be more complicated like fetching configuration from kind of datasource. Then it'd be natural to mock such "expensive" behaviour. But what is preferred way here?
EDIT:
Maybe more clearly: should I mock ArgumentsConfiguration even without writing any implementation (just define its public methods), use mock for testing and deal with real implementation(s) later, or should I use the simplest one in tests, and let them cover this implementation indirectly. But if so, what about testing another Configuration implementation provided later?
Then it'd be natural to mock such "expensive" behaviour.
That's not the point. You're not mocking complex classes.
You're mocking to isolate classes completely.
Complete isolation assures that the tests demonstrate that classes follow their interface and don't have hidden implementation quirks.
Also, complete isolation makes debugging a failed test much, much easier. It's either the test, the class under test or the mocked objects. Ideally, the test and mocks are so simple they don't need any debugging, leaving just the class under test.
The correct answer is that you should mock anything that you're not trying to test directly (e.g.: any dependencies that the object under test has that do not pertain directly to the specific test case).
In this case, because your ArgumentsConfiguration is so simple, I'd recommend using the real implementation until your requirements demand something more complicated. There doesn't seem to be any logic in your ArgumentsConfiguration class, so it's safe to use the real object. If the time comes where the configuration is more complicated, then an approach you should probably take would be not to create a configuration that talks to some data source, but instead generate the ArgumentsConfiguration object from that datasource. Then you could have a test that makes sure it generates the configuration properly from the datasource and you don't need unnecessary abstractions.

Unit-testing a simple collection class

Consider the following class:
public class MyIntSet
{
private List<int> _list = new List<int>();
public void Add(int num)
{
if (!_list.Contains(num))
_list.Add(num);
}
public bool Contains(int num)
{
return _list.Contains(num);
}
}
Following the "only test one thing" principle, suppose I want to test the "Add" function.
Consider the following possibility for such a test:
[TestClass]
public class MyIntSetTests
{
[TestMethod]
public void Add_AddOneNumber_SetContainsAddedNumber()
{
MyIntSet set = new MyIntSet();
int num = 0;
set.Add(num);
Assert.IsTrue(set.Contains(num));
}
}
My problem with this solution is that it actually tests 2 methods: Add() and Contains().
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other. Of course, Contains() now servers as a thin wrapper for List's Contains() which shouldn't be tested in itself, but what if it changes to something more complex in the future? Perhaps a simple "thin wrap" method should always be kept for testing purposes ?
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo or PrivateObject) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems if someday the internal list is replaced by some other collection (maybe C5).
Is there a better way to do this?
Are any of my arguments against the above implementations flawed?
Thanks in advance,
JC
Your test seems perfectly OK to me. You may have misunderstood a principle of unit testing.
A single test should (ideally) only test one thing, that is true, but that does not mean that it should test only one method; rather it should only test one behaviour (an invariant, adherence to a certain business rule, etc.) .
Your test tests the behaviour "if you add to a new set, it is no longer empty", which is a single behaviour :-).
To address your other points:
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other.
True, but that just means you need more tests :-). For example, add two numbers, then call Contains, or call Contains without Add.
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems[...]
Very true, so don't do this. A unit test should always be against the public interface of the unit under test. That's why it's called a unit test, and not a "messing around inside a unit"-test ;-).
There are two possibilities.
You've exposed a flaw in your design. You should carefully consider if the actions that your Add method is executing is clear to the consumer. If you don't want people adding duplicates to the list, why even have a Contains() method? The user is going to be confused when it's not added to the list and no error is thrown. Even worse, they might duplicate the functionality by writing the exact same code before they call .Add() on their list collection. Perhaps it should be removed, and replaced with an indexer? It's not clear from your list class that it's not meant to hold duplicates.
The design is fine, and your public methods should rely on each other. This is normal, and there is no reason you can't test both methods. The more test cases you have, theoretically the better.
As an example, say you have a functions that just calls down into other layers, which may already be unit tested. That doesn't mean you don't write unit tests for the function even if it's simply a wrapper.
In practice, your current test is fine. For something this simple it's very unlikely that bugs in add() and contains() would mutually conspire to hide each other. In cases where you are really concerned about testing add() and add() alone, one solution is to make your _list variable available to your unit test code.
[TestClass]
public void Add_AddOneNumber_SetContainsAddedNumber() {
MyIntSet set = new MyIntSet();
set.add(0);
Assert.IsTrue(set._list.Contains(0));
}
Doing this has two drawbacks. One: it requires access to the private _list variable, which is a little complex in C# (I recommend the reflection technique). Two: it makes your test code dependent on the actual implementation of your Set implementation, which means you'll have to modify the test if you ever change the implementation. I'd never do this for something as simple as a collections class, but in some cases it may be useful.

Unit testing factory methods which have a concrete class as a return type

So I have a factory class and I'm trying to work out what the unit tests should do. From this question I could verify that the interface returned is of a particular concrete type that I would expect.
What should I check for if the factory is returning concrete types (because there is no need - at the moment - for interfaces to be used)? Currently I'm doing something like the following:
[Test]
public void CreateSomeClassWithDependencies()
{
// m_factory is instantiated in the SetUp method
var someClass = m_factory.CreateSomeClassWithDependencies();
Assert.IsNotNull(someClass);
}
The problem with this is that the Assert.IsNotNull seems somewhat redundant.
Also, my factory method might be setting up the dependencies of that particular class like so:
public SomeClass CreateSomeClassWithDependencies()
{
return new SomeClass(CreateADependency(), CreateAnotherDependency(),
CreateAThirdDependency());
}
And I want to make sure that my factory method sets up all these dependencies correctly. Is there no other way to do this then to make those dependencies public/internal properties which I then check for in the unit test? (I'm not a big fan of modifying the test subjects to suit the testing)
Edit: In response to Robert Harvey's question, I'm using NUnit as my unit testing framework (but I wouldn't have thought that it would make too much of a difference)
Often, there's nothing wrong with creating public properties that can be used for state-based testing. Yes: It's code you created to enable a test scenario, but does it hurt your API? Is it conceivable that other clients would find the same property useful later on?
There's a fine line between test-specific code and Test-Driven Design. We shouldn't introduce code that has no other potential than to satisfy a testing requirement, but it's quite alright to introduce new code that follow generally accepted design principles. We let the testing drive our design - that's why we call it TDD :)
Adding one or more properties to a class to give the user a better possibility of inspecting that class is, in my opinion, often a reasonable thing to do, so I don't think you should dismiss introducing such properties.
Apart from that, I second nader's answer :)
If the factory is returning concrete types, and you're guaranteeing that your factory always returns a concrete type, and not null, then no, there isn't too much value in the test. It does allows you to make sure, over time that this expectation isn't violated, and things like exceptions aren't thrown.
This style of test simply makes sure that, as you make changes in the future, your factory behaviour won't change without you knowing.
If your language supports it, for your dependencies, you can use reflection. This isn't always the easiest to maintain, and couples your tests very tightly to your implementation. You have to decide if that's acceptable. This approach tends to be very brittle.
But you really seem to be trying to separate which classes are constructed, from how the constructors are called. You might just be better off with using a DI framework to get that kind of flexibility.
By new-ing up all your types as you need them, you don't give yourself many seams (a seam is a place where you can alter behaviour in your program without editing in that place) to work with.
With the example as you give it though, you could derive a class from the factory. Then override / mock CreateADependency(), CreateAnotherDependency() and CreateAThirdDependency(). Now when you call CreateSomeClassWithDependencies(), you are able to sense whether or not the correct dependencies were created.
Note: the definition of "seam" comes from Michael Feather's book, "Working Effectively with Legacy Code". It contains examples of many techniques to add testability to untested code. You may find it very useful.
What we do is create the dependancies with factories, and we use a dependancy injection framework to substitute mock factories for the real ones when the test is run. Then we set up the appropriate expectations on those mock factories.
You can always check stuff with reflection. There is no need to expose something just for unit tests. I find it quite rare that I need to reach in with reflection and it may be a sign of bad design.
Looking at your sample code, yes the Assert not null seems redundant, depending on the way you designed your factory, some will return null objects from the factory as opposed to exceptioning out.
As I understand it you want to test that the dependencies are built correctly and passed to the new instance?
If I was not able to use a framework like google guice, I would probably do it something like this (here using JMock and Hamcrest):
#Test
public void CreateSomeClassWithDependencies()
{
dependencyFactory = context.mock(DependencyFactory.class);
classAFactory = context.mock(ClassAFactory.class);
myDependency0 = context.mock(MyDependency0.class);
myDependency1 = context.mock(MyDependency1.class);
myDependency2 = context.mock(MyDependency2.class);
myClassA = context.mock(ClassA.class);
context.checking(new Expectations(){{
oneOf(dependencyFactory).createDependency0(); will(returnValue(myDependency0));
oneOf(dependencyFactory).createDependency1(); will(returnValue(myDependency1));
oneOf(dependencyFactory).createDependency2(); will(returnValue(myDependency2));
oneOf(classAFactory).createClassA(myDependency0, myDependency1, myDependency2);
will(returnValue(myClassA));
}});
builder = new ClassABuilder(dependencyFactory, classAFactory);
assertThat(builder.make(), equalTo(myClassA));
}
(if you cannot mock ClassA you can assign a non-mock version to myClassA using new)