基于参数属性的 Mockito 返回值

新手上路,请多包涵

通常在使用 Mockito 时我会做类似的事情:

 Mockito.when(myObject.myFunction(myParameter)).thenReturn(myResult);

是否有可能按照以下方式做某事

myParameter.setProperty("value");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("myResult");

myParameter.setProperty("otherValue");
Mockito.when(myObject.myFunction(myParameter)).thenReturn("otherResult");

所以而不是当仅仅使用参数来确定结果时。它使用参数内的属性值来确定结果。

所以当代码被执行时,它的行为如下:

 public void myTestMethod(MyParameter myParameter,MyObject myObject){
    myParameter.setProperty("value");
    System.out.println(myObject.myFunction(myParameter));// outputs myResult

    myParameter.setProperty("otherValue");
    System.out.println(myObject.myFunction(myParameter));// outputs otherResult
}


这是当前的解决方案,希望可以提出更好的建议。

 private class MyObjectMatcher extends ArgumentMatcher<MyObject> {

    private final String compareValue;

    public ApplicationContextMatcher(String compareValue) {
        this.compareValue= compareValue;
    }

    @Override
    public boolean matches(Object argument) {
        MyObject item= (MyObject) argument;
        if(compareValue!= null){
            if (item != null) {
                return compareValue.equals(item.getMyParameter());
            }
        }else {
            return item == null || item.getMyParameter() == null;
        }
        return false;
    }
}

public void initMock(MyObject myObject){
    MyObjectMatcher valueMatcher = new MyObjectMatcher("value");
    MyObjectMatcher otherValueMatcher = new MyObjectMatcher("otherValue");
    Mockito.when(myObject.myFunction(Matchers.argThat(valueMatcher))).thenReturn("myResult");
    Mockito.when(myObject.myFunction(Matchers.argThat(otherValueMatcher))).thenReturn("otherResult");
}

原文由 BevynQ 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 973
2 个回答

这是一种方法。这使用 Answer 对象来检查属性的值。

 @RunWith(MockitoJUnitRunner.class)
public class MyTestClass {
    private String theProperty;
    @Mock private MyClass mockObject;

    @Before
    public void setUp() {
        when(mockObject.myMethod(anyString())).thenAnswer(
            new Answer<String>(){
            @Override
            public String answer(InvocationOnMock invocation){
                if ("value".equals(theProperty)){
                    return "result";
                }
                else if("otherValue".equals(theProperty)) {
                    return "otherResult";
                }
                return theProperty;
            }});
    }
}

有一种替代语法,我实际上更喜欢它,它可以实现完全相同的效果。由您选择其中的哪一个。这只是 setUp 方法 - 测试类的其余部分应该与上面相同。

 @Before
public void setUp() {
    doAnswer(new Answer<String>(){
        @Override
        public String answer(InvocationOnMock invocation){
            if ("value".equals(theProperty)){
                return "result";
            }
            else if("otherValue".equals(theProperty)) {
                return "otherResult";
            }
            return theProperty;
        }}).when(mockObject).myMethod(anyString());
}

原文由 Dawood ibn Kareem 发布,翻译遵循 CC BY-SA 3.0 许可协议

在 Java 8 中,它甚至比上面所有的都简单:

 when(mockObject.myMethod(anyString()))
    .thenAnswer(invocation ->
        invocation.getArgumentAt(0, String.class));

原文由 Sven 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题