我什么时候应该模拟或不模拟 external/dependent public 接口

When should I mock or not mock external/dependent public interface

我正在尝试为以下内容编写单元测试 class

我想知道我是否需要模拟 Dependency class(考虑到这纯粹是逻辑,没有进行数据库或外部休息调用)。

我在想如果我不嘲笑Dependency class,那么无论如何它都会被CUT覆盖 或者我应该模拟它并为 Dependency class public 接口编写单独的单元测试套件。

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
  }
}

单元测试的主要思想是单独测试单元。否则,这将是一个集成测试。

在这种情况下,您需要为 Dependency 编写一个单独的测试套件,并在 ClassUnderTest 中模拟对它的调用。

如果您正在编写单元测试套件,您可能想要模拟它,如果您的依赖项是纯逻辑,则更是如此。考虑以下场景

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!
  }
}

在你的单元测试中,你会有类似

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

这会失败。但是,您的 class 正在测试中工作正常!它只是将任务委托给另一个 class

您可以通过适当地模拟您的依赖项来避免这种误报

@Test
void testingClass() {
  when(dependency.add(any(), any()).thenReturn(10);
  assertThat(classUnderTest.doSomething(2, 2), is(equalTo(20)));
}

你有两个不同的问题。

模拟的要点是在你的单元测试中没有依赖性来创建隐式行为。您希望单元测试明确您测试的代码单元,以便能够识别回归并声明您的期望 ClassUnderTest 在不同条件下的行为方式。

是否需要覆盖Dependency是关于你的编码标准的问题。总的来说,我发现如果 class 太简单以至于你考虑是否需要测试它,那么通常编写测试应该是一个 none 问题,如果编写测试对我来说经常是一个问题足够表明你真的应该在那里进行测试,因为你不确定正是因为该代码区域是不透明的。