Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java mockito基于参数的属性返回值_Java_Mockito - Fatal编程技术网

Java mockito基于参数的属性返回值

Java mockito基于参数的属性返回值,java,mockito,Java,Mockito,通常,当使用mockito时,我会做如下操作 Mockito.when(myObject.myFunction(myParameter)).thenReturn(myResult); 有没有可能按照这条路线做点什么 myParameter.setProperty("value"); Mockito.when(myObject.myFunction(myParameter)).thenReturn("myResult"); myParameter.setProperty("otherValue

通常,当使用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");
}
私有类MyObjectMatcher扩展ArgumentMatcher{
私有最终字符串compareValue;
公共应用程序ContextMatcher(字符串比较值){
this.compareValue=compareValue;
}
@凌驾
公共布尔匹配(对象参数){
MyObject项=(MyObject)参数;
if(compareValue!=null){
如果(项!=null){
返回compareValue.equals(item.getMyParameter());
}
}否则{
return item==null | | item.getMyParameter()==null;
}
返回false;
}
}
public void initMock(MyObject MyObject){
MyObjectMatcher valueMatcher=新的MyObjectMatcher(“值”);
MyObjectMatcher otherValueMatcher=新的MyObjectMatcher(“otherValue”);
Mockito.when(myObject.myFunction(Matchers.argThat(valueMatcher))),然后返回(“myResult”);
Mockito.when(myObject.myFunction(Matchers.argThat(otherValueMatcher))),然后返回(“otherResult”);
}

是的,您可以使用自定义参数匹配器


有关更多详细信息,请参阅。这里有一种方法。这将使用
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;
            }});
    }
}

在Java 8中,它甚至比上述所有操作都要简单:

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

以下是Kotlin和图书馆的情况

mock<Resources> {
    on {
        mockObject.myMethod(any())
    } doAnswer {
        "Here is the value: ${it.arguments[0]}"
    }
}
mock{
在{
mockObject.myMethod(any())
}多纳{
“以下是值:${it.arguments[0]}”
}
}

您可以使用Mockito 3.6.0执行此操作:

when(mockObject.myMethod(anyString()))
    .thenAnswer(invocation -> myStringMethod(invocation.getArgument(0)));

此答案基于和Martijn Hiemstra的评论,将
getArgumentAt()
更改为
getArgumentAt()

从您的问题中不清楚要模拟的对象是什么,被测试的对象是什么。我添加了一个编辑来演示我希望它的行为。无论我如何尝试阅读此内容,在我看来,你在模仿你想要测试的对象。除非你有令人信服的理由这样做,并且你这样做的方式不会妨碍对象的原始行为,否则这首先就违背了测试的目的。是的,@ylabidi确实有道理。你想做的是可能的,但它“感觉”或“气味”有点尴尬。你应该后退一步,问问这是否真的有必要,为什么有必要。这就是测试的原因之一:糟糕的设计通常会导致测试类的困难或尴尬。如果你想得到更好的建议,你不应该接受答案。一旦你接受了一个答案,大多数人就不会费心提供另一个了。不管它值多少钱,我相信有一个更好的方法可以做到这一点——我可能会在稍后发布一个答案。我喜欢这个想法,但它似乎不完整?这如何区分“值”和“其他值”,并在每种情况下返回不同的答案?您可以通过使lambda变大来区分不同的参数。只需添加一个if来选择写入。它可以是这样的:
invocation->{String param=invocation.getArgumentAt(0,String.class);if(param.equals(“value”))返回“myResultOnValue”;if(param.equals(“otherParam”)返回“myResultOnOtherValue”,否则返回“MyDefaultResult”;
不再需要定义类型。这更简单:when(mockObject.myMethod(anyString()).thenAnswer(invocation->invocation.getArgument(0));Sven和@MartijnHiemstra,你的答案对我很有帮助。谢谢!我不确定是编辑这个答案还是创建一个新答案。请随意将我的答案复制到你的答案中,Sven,我可以删除我的。我可以在“何时”中使用它方法。Mockito.argThat返回null,从而导致异常。@TT。有人修复了链接。我进一步更新了链接,使其始终指向最新版本。您给出的解决方案不允许模拟基于模拟方法的不同参数返回响应。在这种情况下,如果我们希望基于mockObject的参数返回不同的响应.myMethod(字符串参数);如果在测试运行时,如果“参数”是“值”,则返回此值,如果“参数”是“其他值”,则返回其他值。
when(mockObject.myMethod(anyString()))
    .thenAnswer(invocation -> myStringMethod(invocation.getArgument(0)));