0

Well, I have a method that use another method. I have the tests of the secondary method, and now I want to write the unit tests for the main method.

I think that I have to write tests without seeing the code of the method to tests, I mean, I don't have desing the tests thinking in the implementation, so following this, in the tests of the main method I have to tests functionality of the secondary method and the functionality of the main method.

For example, I have two garages with cars. In the garaga a have cars and the number of cars that I have. So I wnat to be able to add a new car to a garaga, remove a car and transfer a car from a garage to another. So I have this methods:

  • One method to add the car to a garage, that have to related the car with the garaga and udpdate the number of the cars. This is when I have a new car.
  • One method to remove a car from a garage, that unrelated the car with the garage and update the number of the cars. This is when I don't have the car anymore, for example because I sold it.
  • On method to transfer the car, that remove the car from the first garage and add the car to the new garage. So this method calls the add method and the remove method.

The code for the transfer method would be something like that:

public void transferCar(garage1, garage2, car)
{
    removeCar(garage1, car);
    addCar(garage2, car);
}

If I test removeCar and addCar and I am sure that they work as expected, to test transfer, I have to test all the cases for addCar and also all the cases for removeCar? Because if I don't know the implementation of transferCar, I don't know if this method use removeCar and addCar, so I don't know if the method works as expected.

In another words, when I test transferCar, the test has to cover 100% of the code of the removeCar, 100% of the code of addCar and 100% of the code of the transferCar method or to ensure that I call the method removeCar once and addCar in the transferCar and it works as expected it is enough, although the removecar and addCar is not covered 100%?

Because if I have to test all the cases of removeCar and addCar, I am doing the same tests twice. So my I have refactored code because removeCar and addCar I use it in many places, but in my test code I have the same tests many times.

This is a very single example, but if I have a method that use few methods and this other methods use antohers, and the main mathod should coverages all the code of all the methods, it would be a very long tests, and a lot of work.

In sumary, when I test a method, I have cover 100% of the code of this method and the 100% of the code of the methods that are used by this method or just to ensure that the main method works as expected and call once each secondary method?

Thanks.

Álvaro García
  • 18,114
  • 30
  • 102
  • 193

1 Answers1

1

TDD does not mean you need to have zero knowledge on implementation details, it is test first programming concept. Unit testing is white box testing and for this one should know exactly what the class implementation is. Black box testing might not need the knowledge of implementation details.

Strictly speaking unit tests should test only the public interfaces of a class and see if we give a 100% coverage for a class (which includes all its private and protected code).

Coverage for a function is to see how many lines of code for that particular function is tested and how many branches(if-else, switch..) are verified.

For your case, I would write a simple test case for transfer car and assert check if the car is transferred from garage1 to garage2. That will 100% coverage for transferCar(). You can then write extensive and multiple test cases to achieve good coverage for addCar() and removeCar() and I hope they are public methods. If they are private then check here

If you want to skip calling the real implementation then mocks are the way to go but that depends on how you have implemented your code.. If a function under test (main function so to say) calls its own instance methods then mocking the called functions are tricky.

Community
  • 1
  • 1
Sam Daniel
  • 1,800
  • 12
  • 22
  • But if it possible, the person who implements the unit test should be different who implements the method to test, becuse in this way it is easy to find errors. So the person who implements the tests perhaps don't know anything about the implementation. – Álvaro García Jul 28 '16 at 19:04
  • So, you mean both parties will know the class structure, public methods, interfaces, what to stub/fake, mock and other details except how each function is individually implemented? not sure if it is a right approach but I guess then we have to accept too much redundant code and extra effort, – Sam Daniel Jul 28 '16 at 19:21
  • Seeing as this question is filed under the tdd tag, "different person should write the test" strikes me as some really peculiar advice. It is however a very good idea to let tests focus on behaviour (i.e. don't follow "1 unit test per method" kind of rules, just test all the possible usages of your system under test. If a test like that exercises 3 different methods of that object, so be it). – prgmtc Jul 29 '16 at 08:56