views:

2682

answers:

12

Do you need to unit test constructors, say I have a ctor like this,

        IMapinfoWrapper wrapper;
        public SystemInfo(IMapinfoWrapper mapinfoWrapper)
        {
            this.wrapper = mapinfoWrapper;
        }

Do I need to write a unit test for this ctor? I don't have any getters for the wrapper variable, so I don't need to test that.

+6  A: 

No. Its functionality will be tested by every other unit test on the class.

Draemon
True, I didn't even think of that. *slaps forehead*
Nathan W
Not every, if there are several constructors or several control flows inside it.
Victor Sergienko
+3  A: 

Yes. If you have logic in your constructor, you should test it.

Edit: You should probably test for when IMapinfoWrapper is null, if that dependency is required. If so, you should have a test that catches your ArgumentNullException

Brian Genisio
I never put any logic in my constructors. Just setters.
Nathan W
+15  A: 

Unit testing is about testing the public states, behaviors, and interactions of your objects.

If you simply set a private field in your constructor, what is there to test?

Don't bother unit-testing your simple accessors and mutators. That's just silly, and it doesn't help anyone.

Justice
If your constructor has, for example, an if (condition), you need to test both flows (true,false).If your constructor does some kind of job before setting. You should check the job is done.
graffic
A: 

I believe in 100% coverage. Also 100% coverage not by simply testing simple interactions by mocking things or just setting and getting things, but more integration/acceptance tests that check functionality. So if you end up writing really good integration/acceptance tests, all of your constructors (and simple methods such as setters and getters) should be called.

digiarnie
100% coverage is a pipe dream and anyone who tells you differently is selling you a shiny new testing tool. ;) I kid... kind of.
Steven Behnke
It might be a problem on legacy systems but if you're starting a new project from scratch, in my opinion 100% is the only way to go. I have worked on systems with 100% coverage. We test drove everything.
digiarnie
OK, you had 100% coverage. But did you test all execution paths?The first doesn't imply the second.
kdgregory
digiarnie
A: 

What behavior of an instance of SystemInfo depends on the value of wrapper?

If anything can go wrong (e.g. null value causes breakage) then I suggest writing scenarios describing each such situation and using them to drive the definition of the appropriate unit tests.

If all of the scenarios end up being dependent on the state or behavior of the private instance of IMapinfoWrapper, then I'd suggest writing unit tests on that class instead.

joel.neely
A: 

Unit Testing is about checking paths of execution, something often refered as Cyclomatic Complexity

If you have no path to choose from, no if, no loop, no GOTO (=P) its not very useful

Eric
I don't agree with you that testing a method without any ifs/loops/gotos doesn't make sense. There is always at least one path of execution, and you should test it even if it is the only one.
Adam Byrtek
+3  A: 

Q: If you are setting a member variable in the constructor, why are you setting it.

A: Because you have a failing unit test that can only be made to pass by setting it in the constructor.

If you use this logic, where you only write code to cause a unit test to pass (Test Driven Development), then you will already have the answer to your question.

John Sonmez
A: 

Not unless you're writing a compiler, because you would only be testing that the compiler could generate code to do assignments, which is normally pointless.

Now, in a more usual situation, if you want to do something else with the wrapper, then maybe there's a point. For example, you could throw an ArgumentNullException if you tried to pass a null, and in theory, that could have a unit test. Even then, the value of the test is pretty minimal.

Personally, I almost never explicitly test constructors. If they are complicated enough to need tests, I tend to feel the code is a little on the smelly side.

Jim Cooper
A: 

If the constructor contains some logic, such as initialize a class, I think you should test the very constructor. Or you can talk to the developer that putting initialization in the constructor will cut the testability of code under test.

Magus
A: 

In many FDA-regulated environments, more critical code must be 100% tested...including the construction of classes. So, the testing of constructors is sometimes necessary regardless of reasoning to or not to test them. Also, companies that use static analysis tools will need to make sure ALL data members of a class are properly initialized in order to not have errors although the code may run smoothly and free of errors. Usually data member initialization is done in the constructor...just food for thought.

Brandon
A: 

Testing accessors and mutators is also necessary unless the developer has ensured that no state logic can be changed. For instance, if one uses the design pattern for a Singleton, often times accessors or properties are used, and if the class is not initialized, it is done from the accessor since the constructor is private. In C++, one can make their functions const or static in which data members of the class cannot be changed. (Note: Even using static is a bit risky since those variables are often global.) However, without a test, if someone fails to use preventative measures, how can you guarantee with a 100% accuracy that what is written cannot become a failure over time? Maintenance is hardly foolproof.

Brandon
+1  A: 

It depends.

I wouldn't bother writing a dedicated constructor test for something so simple as the example you gave.

However, if you have logical tests in the constructor such as a parameter validation, then yes, absolutely. Although, like the original poster, I do no work in the constructor if possible, it's common that parameter validation must be done. In this case it is unavoidable to keep the constructor from doing some work. If there's logic in the constructor, there's always the chance that it could be wrong, hence I treat it just like any other method call and test it appropriately.

Mark Simpson