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.

I've been practicing behaviour driven development (BDD). I understand that you have to write tests that test the behaviour of the code, and this will allow the design of your code to evolve and take shape.

When doing BDD and I find I need to refactor my code into a better design, and that refactor happens to involve extracting some code into a new class, when do I start writing tests for that new class?

Or are tests not needed for that class at all since it's a implementation detail and the behaviour of it should already be tested with the existing test coverage?

share|improve this question

3 Answers 3

I'm guessing you're refactoring because the class is violating SRP, i.e. it's got an extra feature that doesn't belong there. So, what's going to happen is that the feature is going to move from one existing class to a new class. The way I've handled this in the past is:

  1. Check I've got atomic tests that cover that feature.
  2. Refactor and extract the class. At this point the atomic tests become integration tests.
  3. Refactor/move those tests, so that they're no longer integration tests on the original class, but atomic tests on the new class
  4. Fix any existing tests on the old class that now have dependencies on the new class that need mocking.

The way I look at this is the number of features and tests in your codebase has remained the same, they've just been reorganised.

share|improve this answer

When doing BDD and I find I need to refactor my code into a better design, and that refactor happens to involve extracting some code into a new class, when do I start writing tests for that new class?

Start refactoring as soon as you identify the problem. If you see that you can extract some functionality into new class, do it right away, but first make sure all tests are passing.

Or are tests not needed for that class at all since it's a implementation detail and the behaviour of it should already be tested with the existing test coverage?

Yes, you do need to test that class as well. Extra tests will not do harm, and may catch possible bugs that got through in old tests.

If you are following SOLID, and using mock classes to test behaviour, then you'll need to change the existing tests. If not, then just leave tests as they are.

share|improve this answer
    
But once I've refactored the code into a new class, do I need to add tests for that new class? That's what I basically want to know –  Bobby Lei Jun 20 '13 at 6:47
    
@BobbyLei Ok, sorry I misunderstood your second question. See edit –  BЈовић Jun 20 '13 at 7:06
    
Thanks for your help! –  Bobby Lei Jun 20 '13 at 8:03

Part of the joy of BDD is moving away from that word, "test".

Instead, we have examples which illustrate how the code behaves, both at a system and a unit level.

Those examples let us question whether the behavior of the code is appropriate. For instance, we might have a "Shop" class which is responsible for recording stock, as well as for taking orders.

When we look at the examples, we can see the following behaviors illustrated:

should Record Stock
should Take Orders

One of the things we can do when we stop thinking about "tests" is think, "should it? Should it really?"

We can see that these are two different aspects of behaviour, so we know that maybe the shop should delegate those aspects. We can start thinking about what a shop should really do.

What's the purpose of a shop? Well, it's to make money for the owner, and to provide goods for customers. Recording stock and taking orders are just part of that.

So maybe a shop:

should Make Money
should Provide Goods for Customers

Wow. We've got the ability to take orders and to record stock, but we haven't actually got any way of finding out if we're making money or providing the correct goods. Maybe we should do that, too...

By using natural language, and talking about what a piece of code should do, we can have conversations with our business to see if we understand their requirements correctly, then carry the language they use into the code.

At that point, a lot of things become more obvious.

  • If our code isn't doing what it says it should, it might be the wrong code.
  • If our code is doing what it should, but doesn't say it's doing it, we need to refactor things like method and variable names, and maybe extract some methods too.
  • If something else should be doing what our code is doing, we need to move things into different classes.
  • If our application isn't doing what it should, we can have a chat with the business about what they really want it to do instead.

Using a shop is a pretty simple example, but I hope you can see that by thinking of code not in terms of "test" and "how to test", but in terms of "how it should behave", we end up using the Single Responsibility Principle... well, more responsibly. And we probably learn a lot about our domain, while creating readable and maintainable code, at the same time.

This is the heart of BDD. I find that experienced BDDers tend to need to refactor less, because they end up creating things that adhere to the SRP to begin with.

share|improve this answer

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.