6

Possible Duplicate:
Is Unit Testing worth the effort?

I know what is the purpose of unit tests generally speaking, but I found some things that bother me.

1) Purpose of tests early bug discovery. So, in some of later iterations, if I make some changes in code, automated test have to alarm me and tell me that I've screwed up some long ago forgotten piece of my software.

But, say that I have class A and say that is interact with some others class' instance, call it class B.

When one writes unit test for class A, he has to mock class B. So, in some future, if one makes some changes in class B, and that causes some bugs, they will reflect only in class B's unit test, not in A's ('cause A's test doesn't use real class B, but it's mock with fixed inputs and outputs). So, I can't see how could unit test do early notifying of made bugs that one isn't aware of? I'm aware of possible bugs in class that I'm changing, I do not need unit test for it, I need test to alarm me of consequences of my changes that makes bug in some "forgotten" class, and that isn't possible with unit tests. Or am I wrong?

2) When writing mocks and right expectations of calling methods, their inputs and returning values, one has to know how class-under-test is going to be implemented. And I think that that contradicts with test driven development. In TDD one writes tests first, and, driven by them, one writes a code. But I can't write right expectations (and tests in general) unless I write code that has to be tested. That contradicts with TDD, right?

Both of those problems could be solved if I used real objects instead of mocks. But that isn't unit testing then, right? In unit test class-under-test has to be isolated form the rest of the system, not using real classes but mocks.

I'm sure that I'm wrong somewhere, but I cannot find where. I've been reading and reading and I can't find what have I understood wrong.

Cœur
  • 37,241
  • 25
  • 195
  • 267
SadClown
  • 648
  • 8
  • 16

5 Answers5

4

I have just implemented TDD and unit testing for the first time. I think its great, and I have never used it in a contiguous integration environment, where I imagine its even more valuable.

My process:

  1. Create the skeleton of class where business logic will go (be it a serivce layer, or domain object, etc).
  2. Write the test, and define the method names and required functionaility in the test - which then prompts my ide to write the skelton method (a small but nice plus)
  3. Then write the actual class methods being tested.
  4. Run tests, debug.

I can now no longer write code without first writing its test, it really does aid develop. You catch bugs straight away, and it really helps you mentally order your code and development in a structured simple manner. And of course, any code that breaks existing functionality is caught straightaway.

I have not needed to use mock objects yet (using spring I can get away with calling service layer, and controller methods directly).

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
3

Strictly speaking, you spend more time in writing unit test rather than concentrating on the actual code.

there is no way you can achieve 100% code coverage. I do unit test my application, but I feel its not worth it. But not every one agrees with it.

If you change a piece of code, your unit test fail and figure out why its failing but for me its not worth it.

I am not big fan of Unit testing... You mock everything but mocking is big task..........

But now a days companies are trying for TDD approach.

David Aleu
  • 3,922
  • 3
  • 27
  • 48
Hari Gillala
  • 11,736
  • 18
  • 70
  • 117
  • 1
    Yes, "If you change a piece of code, your unit test fail and figure out why its failing", but if you mock everything, when I change some method, only that method's test could fail and nothing else. I'm talking about unit tests, not about tests in general. If I mock everything, then changes in one class won't have consequences in others classes' tests. If I do not mock everything, well, that isn't unit test, as far as I know. – SadClown Sep 23 '11 at 10:57
  • @sadClown thats not the idea of mock objects, afaik. Mock objects are used to represent, for example a http request. You don't test the mock objects, they are used within your test and passed to the code you are testing. – NimChimpsky Sep 23 '11 at 12:27
2

Simple answer: Yes, they are useful for real.

TDD is nice and all in theory but I've hardly ever seen seen it done in practice. Unittests are not bound to tdd, however. You can always write unittests for code that works to make sure it still works after changes. This usage of unittests have saved me countless hours of bugfixing because the tests immediately pointed out what went wrong.

I tend to avoid mocks. In most cases, they're not worth it in my opinion. Not using mocks might make my unittest a little more of an integrationtest but it gets the job done. To make sure, your classes work as designed.

Markus
  • 2,174
  • 2
  • 22
  • 37
  • what is the approach you use for mocking object in your code? Is there any simple mocking magic you got to mock object? Or you do not use objects at all in your code? – Hari Gillala Sep 23 '11 at 09:48
2

Unit Tests itself aren't stupid, it depends of your project.

I think Unit Tests are good, not just in TDD development but in any kind of project. The real pro for me is that if you wrap crucial code in your project with Unit Tests, there's a way to know if what you meant with it is still working or not.

For me, the real problem is that if someone is messing your code, there should be a way for him/her to know if the tests are still succedding, but not by making them run manually. For instance, lets take Eclipse + Java + Maven example. If you use Unit tests on your Maven Java Project, each time anyone build it, the tests run automatically. So, if someone messed your code, the next time he build it, he'll get a "BUILD FAILED" Console error, pointing that some Unit Tests failed.

So my point is: Unit Tests are good, but people should know that they're screwing things up without running tests each time they change code.

everton
  • 7,579
  • 2
  • 29
  • 42
1

0) No, it doesn't. Sound stupid, I mean. It is a perfectly valid question.

The sad fact is that ours is an industry riddled with silver bullets and slick with snake oil, and if something doesn't make sense then you are right to question it. Any technique, any approach to any part of engineering is only ever applicable in certain circumstances. These are typically poorly documented at best, and so it all tends to deteriorate into utterly pointless my-method-is-better-than-yours arguments.

I have had successes and failures with unit testing, and in my experience it can be very useful indeed, when correctly applied.

It is not a good technique when you're doing a massive from-scratch development effort, because everything is changing too rapidly for the unit tests to keep up. It is an excellent technique when in a maintenance phase, because you're changing a small part of a larger whole which still needs to work the way it's supposed to.

To me, unit testing is not about test-driven development but design-by-contract: the unit test checks that the interface has not been violated. From this, it's pretty easy to see that the same person should not be writing a unit and its corresponding unit test, so for very small-scale stuff, like my own pet projects, I never use it. In larger projects, I advocate it - but only if design-by-contract is employed and the project recognizes interface specifications as important artefacts.

Unit testing as a technique is also sensitive to the unit size. It is not necessarily the case that a class is testable on its own, and in my experience the class is generally too small for unit testing. You don't want to test a class per se, you want to test a unit of functionality. Individually deployable (installable) binaries, eg jars or DLLs, make better candidates in my book, or packages if you're in a Java-style language.

Uffe
  • 10,396
  • 1
  • 33
  • 40