模拟void方法,改变他们的论点

mar*_*tin 5 java unit-testing mocking mockito

我有一个界面,看起来像这样

public interface ParameterProvider
{
    void provideParameter(Map<String, String> parameters);
}
Run Code Online (Sandbox Code Playgroud)

它的一个实例用于我想要编写单元测试的方法:

@Override
public void process(...)
{
    ...
    Map<String, String> parameters = new HashMap<String, String>();
    parameterProvider.provideParameter(parameters);
    ...
}
Run Code Online (Sandbox Code Playgroud)

我如何模拟ParameterProvider对参数执行操作,传递给它的provideParameter-method?

我的第一个想法是将返回类型更改voidMap并实际返回修改后的内容Map(无论如何它似乎更好).然后测试没问题:

when(parameterProvider.provideParameter(anyMap())).thenReturn(MY_PARAMETERS);
Run Code Online (Sandbox Code Playgroud)

但是,由于接口在框架中使用,由于某些奇怪的原因似乎要求方法无效,因此现在不能选择.

有没有办法嘲笑这件事.我正在使用Mockito,但如果有其他模拟框架可以完成工作,我不需要坚持使用它.

编辑:我也尝试使用doAnwser,但我没有看到如何修改传递给该方法的参数:

doAnswer(new Answer() {
    public Object answer(InvocationOnMock invocation) {
        Object[] args = invocation.getArguments();
        args[0] // that's the argument I want to modify
        return null;
    }})
.when(parameterProvider).provideParameter(anyMap());
Run Code Online (Sandbox Code Playgroud)

Bri*_*new 10

Mockito.doAnswer()将允许您模拟void方法并通过您自己的闭包/类实现Answer来操纵传递给它的参数(前提是您的参数是可变的).

所以鉴于你的代码:

doAnswer(new Answer() {
    public Object answer(InvocationOnMock invocation) {
        Object[] args = invocation.getArguments();
        args[0] // that's the argument I want to modify
        return null;
    }})
 .when(parameterProvider).provideParameter(anyMap());
Run Code Online (Sandbox Code Playgroud)

args [0]将是一个Map(通过调试器检查)并假设它是可变的,你应该能够在你的匿名类中填充/更改它,例如

((Map)args[0]).put(x, y);
Run Code Online (Sandbox Code Playgroud)