Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

EDIT: I think that no one really understood the question. I think that this is partly my fault as well, so I hop it gets better now. The thing is, I am perfectly aware of the existence of mocking frameworks, and so on. This is not the problem. The problem is what happens when you change your method's implementation and it simply doesn't call the mock anymore, and you start seeing a bunch of red lights in your test stack, because your mocks aren't called the way the way they should? Unit or Integration test, something should be done here, right? Another one, if I start writing different mock methods for every test condition I like, what happens if I decide to change the signature of the class I'Ve mocked? All my tests go to the trash bin, right? Is this normal, can it be avoided? Is it a design problem?

I hope I am not confusing you more, guys.

How effective are unit tests in reality? I am under the impression that at some point unit tests turn into tests that test the dependency between the object under test and another object. Sure, one can always abstract dependencies using interfaces, but what happens when even the interfaces should be changed? What if the unit under test no longer relies on those dependencies?

If our tests fail because of dependency issues, does it mean they are too coupled to our code? Also, do we have to change them every time when we change the dependencies? If it happens quite often, is this a sign that our design is wrong?

I tended to believe that unit tests are an effective way to test ensure robustness, but if they are too coupled to the dependencies that our objects have with other objects (be they expressed as interfaces), it simply leads to more time wasted in fixing those tests to pass the new design. Am I wrong?

NOTE: Someone mentioned that when we test the dependencies between two objects, it is no longer considered unit testing, but rather, integration testing. I don't know what to believe in, any longer

share|improve this question
    
Before I answer I want to ask - are you really not aware of mocking, like people here have interpreted? Because I have interpreted otherwise, that you don't see the point in testing object relationships with mocking if it doesn't really "produce results" but only "delegates work". If that's the case, I'll give you my answer. Let me know. –  Yam Marcovic Oct 12 '11 at 12:44
    
Nope, I am clearly aware of mocking tools. Please, see the edit, hope my question is clear now. –  user802232 Oct 13 '11 at 7:58
add comment

migrated from stackoverflow.com Oct 12 '11 at 12:22

This question came from our site for professional and enthusiast programmers.

3 Answers

The person that told you testing dependencies is integration testing rather than unit testing is indeed correct. Unit testing normally consists of creating mock objects of any dependencies and testing a single Class as a single "unit". You are only testing that it calls the correct methods on its dependencies and returns the correct things IF the dependencies return the correct things. This is one of the good reasons for using interfaces for your Classes as you can easily create a mock from an interface using for example EasyMock.

Unit tests are very useful as long as they are done right, but I do believe that some people take them too far. You don't need 100% code coverage, just make sure anything that isn't obviously correct is reasonably tested. I recommend adding system tests as well for any complicated system - these tests won't mock anything, they just test the system as a whole.

You may want to read some of the answers at http://stackoverflow.com/questions/16860/getting-started-with-unit-testing for getting the most out of your unit testing.

share|improve this answer
2  
+1 for pointing out the waste of time in 100% test coverage fanatics. –  maple_shaft Oct 12 '11 at 12:40
2  
Creating mocks for concrete classes hasn't been harder than doing it for interfaces for several years, yet people keep polluting their projects with pointless interfaces... –  Michael Borgwardt Oct 12 '11 at 15:08
1  
About 100% coverage, it depends on the language. For a compiled language like Java, sure, full coverage is not needed. But for a language like Ruby any line could have a typo that only comes out when the actual code is hit. –  Chris Pitman Oct 12 '11 at 19:01
    
@Chris Good point about Ruby, I guess there are pros for why Java requires you to be absurdly specific when you code. –  maple_shaft Oct 13 '11 at 11:26
add comment

How effective are unit tests in reality?

That depends on your problem domain! I consider them to almost always to be worth it, they allow you to refector without fear!

I am under the impression that at some point unit tests turn into tests that test the dependency between the object under test and another object. Sure, one can always abstract dependencies using interfaces, but what happens when even the interfaces should be changed? What if the unit under test no longer relies on those dependencies?

Are you aware of Test Doubles, which also covers mocking? This should help you Unit (and Integration) test more effectively.

Using TDD, if your interface changes then in theory you should be altering your test first to indicate what your desired outcome should be, then change the actual code to pass the test. So the whole Red-->Green-->Refactor cycle.

If our tests fail because of dependency issues, does it mean they are too coupled to our code? Also, do we have to change them every time when we change the dependencies? If it happens quite often, is this a sign that our design is wrong?

See my point above about Test Doubles. However, sometimes you can't or don't want to use a Test Double. In that case you're starting to test the interaction between 2+ components, which is often called Integration Testing.

I tended to believe that unit tests are an effective way to test ensure robustness, but if they are too coupled to the dependencies that our objects have with other objects (be they expressed as interfaces), it simply leads to more time wasted in fixing those tests to pass the new design. Am I wrong?

You're not wrong, I think your approach just needs some Test Double/Mock/Dependency Injection tweaks

NOTE: Someone mentioned that when we test the dependencies between two objects, it is no longer considered unit testing, but rather, integration testing. I don't know what to believe in, any longer

IMO, that person is correct - those sorts of tests are integration tests.

Also for slightly more advanced thinking in this space, lookup BDD as a complimentary approach to unit testing

share|improve this answer
1  
"I consider them to almost always to be worth it, they allow you to refector without fear!" Not entirely true. Race conditions can and will slip by if you only rely on tests. –  Coder Oct 12 '11 at 12:50
add comment

You seem flustered about a number of issues, I will try and address as many as I can:

I am under the impression that at some point unit tests turn into tests that test the dependency between the object under test and another object. Classes and components have dependencies on other classes and components, yes. Thus we have a situation where the unit test for component A needs to test assertions on the functionality of A, and the dependency on component B should be accounted for. Under Integration Testing, we are testing the appropriate interaction between the testing component A and its dependency in component B. However in true Unit Testing, we assume that the behavior of component B is understood and well tested.

We can use a Mocking framework to create a dummy component B that has predefined behavior we specify. The value of mocking then is that we can have unit tests for specific scenarios of component A Method 2 for instance:

  • Test Return Value of Component A Method 2 when argument passed is 4

  • Test Return Value of Component A Method 2 when argument passed is 4 and mocked dependency component B returns 12.

  • Test exception is throw from Component A Method 2 when mocked dependency component B returns 15.

  • Etc...

    I tended to believe that unit tests are an effective way to test ensure robustness, but if they are too coupled to the dependencies that our objects have with other objects (be they expressed as interfaces), it simply leads to more time wasted in fixing those tests to pass the new design. Am I wrong?

This could be a sign of high coupling and low cohesion and violations of the single responsibility of a class if your tests are extraordinarily complicated and prohibitively brittle. Unit tests are of less importance in this case as the major underlying design issues should be addressed first. This will be more beneficial to software quality.

OTOH, if you find that most of the behavior of a component is actually inside of the dependent components, then it sounds like a wrapper component or pass-through component of some kind and test coverage of this component may be overkill.

share|improve this answer
    
how does one test wrappers then? –  user802232 Oct 13 '11 at 8:01
    
@user802232 This is a point of confusion that I see in a LOT of developers who are new to unit testing. They write a unit test for every method of basically a wrapper class that contains no business logic whatsoever. They then get confused because the unit tests are insanely simple and seem downright pointless. They assume that they must be doing something wrong, when in fact they aren't they are doing it perfectly. The problem is that it is TOO easy to test wrappers, thus why I feel it is pointless. –  maple_shaft Oct 13 '11 at 11:09
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.