views:

111

answers:

5

Presume you have a class which passes all its current unit tests.

If you were to add or pull out some methods/introduce a new class and then use composition to incorporate the same functionality would the new class require testing?

I'm torn between whether or not you should so any advice would be great.

Edit:

Suppose I should have added I use DI (Dependency Injection) therefore should I inject the new class as well?

+2  A: 

Not in the context of TDD, no, IMHO. The existing tests justify everything about the existence of the class. If you need to add behavior to the class, that would be the time to introduce a test.

That being said, it may make your code and tests clearer to move the tests into a class that relates to the new class you made. That depends very much on the specific case.

EDIT: After your edit, I would say that that makes a good case for moving some existing tests (or a portion of the existing tests). If the class is so decoupled that it requires injection, then it sounds like the existing tests may not be obviously covering it if they stay where they are.

Yishai
That's what I was thinking - though what should I do regards DI? Should I create and initialize a concrete implementation of the new class in the constructor and not worry about injecting it - after all it is doing the same as what it was doing before?
Finglas
The whole point of DI is being able to interchange components. If you will never (and I mean NEVER) have to swap out your new class for something else, I'd just go ahead and construct it yourself.
Mike Daniels
A: 

I would say no. It is already being tested by the tests run on the old class.

willcodejavaforfood
+4  A: 

Initially, no, they're not necessary. If you had perfect coverage, extracted the class and did nothing more, you would still have perfect coverage (and those tests would confirm that the extraction was indeed a pure refactoring).

But eventually - and probably soon - yes. The extracted class is likely to be used outside its original context, and you want to constrain its behavior with tests that are specific to the new class, so that changes for a new context don't inadvertently affect behavior for the original caller. Of course the original tests would still reveal this, but good unit tests point directly to the problematic unit, and the original tests are now a step removed.

It's also good to have the new tests as executable documentation for the newly-extracted class.

Carl Manaster
A: 

As others have said, it's probably not entirely needed right away, since all the same stuff is still under test. But once you start making changes to either of those two classes individually, you should separate the tests.

Of course, the tests shouldn't be too hard to write; since you have the stuff being tested already, it should be fairly trivial to break out the various bits of the tests.

Adam Jaskiewicz
+1  A: 

Well, yes and no.

If I understand correctly, you have written tests, and wrote production code that makes the tests pass - i.e. the simplest thing that works.

Now you are in the refactoring phase. You want to extract code from one class and put it in a class of its own, probably to keep up with the Single Responsibility Principle (or SRP).

You may make the refactoring without adding tests, since your tests are there precisely to allow you to refactor without fear. Remember - refactor means changing the code, without modifying the functionality.

However, it is quite likely that refactoring the code will break your tests. This is most likely caused by fragile tests that test behavior, rather than state - i.e. you mocked the the methods you ported out.

On the other hand, if your tests are primarily state-driven (i.e. you assert results, and ignore implementation), then your new service component (the block of code you extracted to a new class) will not be tested. If you use some form of code coverage testing tool, you'll find out. If that is the case, you may wish to test that it works. Might, because 100% Code Coverage is neither desirable nor feasible. If possible, I'd try to add the tests for that service.

In the end, it may very well boil down to a judgment call.

Assaf Stone