0

I am trying to write unit test for the following class

I was wondering if I need to mock the Dependency class (consider that it is purely logic no DB or external rest calls are made).

I was thinking if I will not mock the Dependency class, then anyway it will be covered by the CUT or should I mock it and write separate unit test suite for Dependency class public interface.

public class ClassUnderTest {
  @Autowired
  private Dependency dependency;

  public Object foo(){
    // do something
    var = dependeny.bar(args..);
    // do somethig
  }
}
public class Dependency {
  public Object bar(args..){
    // do something
  }
}
flash
  • 267
  • 2
  • 7
  • It depends on what Dependency is. And given your example is arbitrary, it is unanswerable. – Michael Oct 27 '20 at 11:09
  • @Michael I'm clear and "makes sense" with the answers given to this question, but still I would love to know your thoughts, idk if this could help but my Dependency class is a simple class which performs bunch of jolt transformations. – flash Oct 27 '20 at 11:26
  • Take a look at [my answer](https://stackoverflow.com/a/64416342/6413377) to another question that might also be helpful. – pirho Oct 27 '20 at 12:12

3 Answers3

3

The main idea of unit testing is to test units separately. Otherwise, it would be an integration test.

In this case, you need to write a separate test suite for Dependency, and mock the call to it in ClassUnderTest.

amseager
  • 5,795
  • 4
  • 24
  • 47
2

If you're writing your unit test suite you probably want to mock it, even more if your dependency is pure logic. Consider the following scenario

public class ClassUnderTest {
  @Autowired
  private Dependency dependency;

  public int doSomething(int a, int b) {
    return dependency.add(a, b) * 2;
  }
}

public class Dependency {
  public int add(int a, int b) {
    return 0; // bug here!
  }
}

In your unit test, you'll have something like

@Test
void testingClass() {
  assertThat(classUnderTest.doSomething(2, 2), is(equalTo(8)));
}

which will fail. However, your class under test is working fine! It's just delegating the task to another class

You can avoid this false positives by mocking properly your dependencies

@Test
void testingClass() {
  when(dependency.add(any(), any()).thenReturn(10);
  assertThat(classUnderTest.doSomething(2, 2), is(equalTo(20)));
}
Alberto S.
  • 7,409
  • 6
  • 27
  • 46
2

You have two separate question.

The point of mocking is to not have dependencies in your unit tests creating implicit behavior. You want unit tests to be explicit about the code unit you test to be able to identify regression and also declare your expectation how ClassUnderTest behaves in different conditions.

Whether you need to cover Dependency is a question concerning your coding standards. In general I find if a class is so simple that you ponder whether you need to test it, then usually writing the test should be a none issue and if writing a test is an issue to me that often enough indicates you really should have a test there, given you are unsure precisely because that code region is opaque.