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

Mockito Capture argument of a Constructor in mockConstruction

我有以下 classes:

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

}

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

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

}

目前,我正在为 Foo class 编写测试,由于未注入 Bar,我正在使用 mockConstruction 来强制 [=12= 的所有实例] 在 mockConstruction 调用之后创建以进行模拟。但我想捕获该构造函数(即监听器)的参数。我该怎么做?

Foo 上写 unit-test 时不需要捕获 Listener。因为您正在使用 Mocking 框架,该框架将间接依赖项与测试隔离开来 class.

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

Foo -> Bar -> Listener -> Other -> Other2 -> ...

当你在 Foo 上测试时,使用模拟框架制作一个 MockedBar 并消除 Bar 的依赖路径。那么,依赖路径就变得很简单了:

Foo -> MockedBar  

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

为此,只需稍微重构您的代码即可。首先,在 Foo:

中添加一个 package-private 构造函数
public class Foo {

    private final int mIntField;
    private final Bar mBarObject;

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

    // package-private constructor, for test only.
    Foo(int intField, Bar bar) {
        mIntField = intField;
        mBarObject = bar;
    }
}

其次,通过constructor-injection初始化并注入mockedBarFoo

public class FooTest {
    
    private Foo foo;

    @Before
    public void setup() {
        int intField = 123;
        Bar mockedBar = mock(Bar.class);
        when(mockedBar.invokeListener()).thenReturn(something);
        foo = new Foo(intField, mockedBar);
    }

    @Test
    public void test_foo() {
        // test your foo
    } 
}

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