Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing a method that calls another method

What is the best way to unit test a method that calls into multiple methods, for example:

modify(string value) {     if(value.Length > 5)  replaceit(value);      else changeit(value); } 

This pseudo code has a modify method that (currently) calls either replaceit() or changeit(). I have already wrote tests for replaceit and changeit, so writing a new test for modify will be 99% the same set of code. I need to test it thought because it may change in the future.

So do I copy paste the existing test code? Move the test code to a common function? Any other ideas? I'm not sure of the best practice here.

like image 809
NotDan Avatar asked Dec 12 '08 17:12

NotDan


People also ask

Which method is used for unit testing?

Unit Testing Techniques:Black Box Testing - Using which the user interface, input and output are tested. White Box Testing - used to test each one of those functions behaviour is tested. Gray Box Testing - Used to execute tests, risks and assessment methods.

How do you unit test a method that calls a static method?

All you need to do is wrap the static method call inside an instance method and then use dependency injection to inject an instance of the wrapper class to the class under test.

How do you mock another method that is being tested in the same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

How do you call a test method?

You can call the method from a test class, similar to how you call method from other classes. ClassName classInstanceObj = new ClassName(); classInstanceObj. MethodName();


2 Answers

This is a classic state-based test vs. behavior-based test scenario.

In this ridiculously simple example testing the output is fine. At some point though, you'll run into tests where inspecting the state after execution is complicated. Instead you want to check the behavior (e.g. verify that changeit was called with a specific value).

At that point you probably should look into a mock object framework like Rhino.Mocks (.Net) or Mockito (Java) and start writing more interface based code.

like image 151
Eric Nicholson Avatar answered Oct 20 '22 19:10

Eric Nicholson


You have a number of options. Which one is best depends on details that aren't clear from your question.

  • test modify just as if it were an unrelated method. Advantage: it might at some point become one.
  • just test that you got the if-statement right. That is, just test enough that the tests force you to write the implementation you need (where calling replaceit and changeit is just the simplest implementation that could possibly work. If your are practicing TDD, this should come naturally to you. Advantage: high test coverage without much duplicated effort.
  • Subclass and Override Method (this is a dependency breaking technique from the book "Working Effectively With Legacy Code"): Test the method on a subclass that you introduce solely for testing purposes, which overrides replaceit and changeit with canned answers or so that they set sensing variables (variables that indicate whether the method has been called with the right value(s)). Advantage: might possibly simplify your tests (or not), sometimes even just make testing possible.
  • Extract a new class for the replaceit and changeit methods, including an interface for that class. Stub or Mock that interface when testing modify. Advantage: might both make your design more testable and better decoupled/reusable in general (or not).
like image 35
Ilja Preuß Avatar answered Oct 20 '22 19:10

Ilja Preuß