Mockito 在mockConstruction中捕获构造函数的参数

Cha*_*mon 6 java unit-testing mockito

我有以下课程:

public class Bar {
  
  private final Listener mListener;
  
  public Bar(Listener listener) {
    mListener = listener;
  }

}

public class Foo {
  
  private final int mIntField;
  private final Bar mBarObject;

  public Foo(int intField) {
    mIntField = intField;
    mBarObject = new Bar(new Listener() { ... });
  }

}
Run Code Online (Sandbox Code Playgroud)

目前,我正在为Foo类编写测试,因为Bar没有注入,所以我使用mockConstruction强制模拟调用Bar后创建的所有实例。mockConstruction但我想捕获该构造函数(即监听器)的参数。我怎样才能做到这一点?

Mic*_*ksa 11

// Map of created Bar(s) and its constructor arguments
// If single object is expected to be created then simple list of objects is enough
final Map<Bar, List<Object>> constructorArgs = new HashMap<>();
try (MockedConstruction<Bar> mockedBarClass = Mockito.mockConstruction(Bar.class,
        (mock, context) -> constructorArgs.put(mock, new ArrayList<>(context.arguments())))) {

    // WHEN
    new Foo(1);

    // THEN
    assertThat(mockedBarClass.constructed()).hasSize(1);
    // Get created object
    Bar createdBar = mockedBarClass.constructed().get(0);
    // Assert constructor arguments
    assertThat(constructorArgs.get(createdBar)).hasSize(1);
    assertThat(constructorArgs.get(createdBar).get(0)).isInstanceOf(Listener.class);
}
Run Code Online (Sandbox Code Playgroud)


Kai*_*ang 2

Listener当您在 上编写单元测试时,不需要捕获Foo. 因为您使用的是模拟框架,它将间接依赖项与测试类隔离。

我们做一个简单的图作为例子。假设您的实际依赖路径如下所示:

Foo -> Bar -> Listener -> Other -> Other2 -> ...
Run Code Online (Sandbox Code Playgroud)

当你测试时Foo,使用模拟框架来制作MockedBar并消除 的依赖路径Bar。那么,依赖路径就变得非常简单:

Foo -> MockedBar  
Run Code Online (Sandbox Code Playgroud)

因此,您可以Foo轻松测试您的。

为此,只需稍微重构您的代码即可。首先,在您的中添加一个包私有构造函数Foo

Foo -> Bar -> Listener -> Other -> Other2 -> ...
Run Code Online (Sandbox Code Playgroud)

其次,通过构造函数mockedBar注入初始化并注入。Foo

Foo -> MockedBar  
Run Code Online (Sandbox Code Playgroud)

就这样。现在,您不再需要使用魔法功能mockConstruction了。