简体   繁体   English

方法内部的Mockito模拟对象

[英]Mockito mock objects inside a method

I am writing a test for verifying the behavior of my class when receiving different responses from a SOAP Service. 我正在编写一个测试,以验证从SOAP服务接收到不同响应时类的行为。 I use Jaxb, so my response contains JaxbElements , and for many of them, I need to write a mock, like that: 我使用Jaxb,所以我的响应包含JaxbElements ,对于其中许多我需要编写一个模拟程序,如下所示:

JAXBElement<String> mock1 = mock(JAXBElement.class);
when(mock1.getValue()).thenReturn("a StringValue");
when(result.getSomeStringValue()).thenReturn(mock1);

JAXBElement<Integer> mock2 = mock(JAXBElement.class);

when(mock2.getValue()).thenReturn(new Integer(2));
when(result.getSomeIntValue()).thenReturn(mock2);
... <continue>

what I would like to do, is refactorize this code that way: 我想做的是这样重构代码:

when(result.getSomeStringValue())
    .thenReturn(mockWithValue(JAXBElement.class, "a StringValue");

when(result.getSomeIntValue())
    .thenReturn(mockWithValue(JAXBElement.class, 2));

and define a method: 并定义一个方法:

private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) {
    JAXBElement<T> mock = mock(jaxbElementClass);
    when(mock.getValue()).thenReturn(value);
    return mock;
}

when I execute the code before the refactoring everything works properly. 当我在重构之前执行代码时,一切正常。 Unfortunately, when I execute the the code after the refactoring, I receive this error: 不幸的是,当我在重构后执行代码时,我收到此错误:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at com.mypackage.ResultConverterTest.shouldConvertASuccessfulResponseWithAllTheElements(ResultConverterTest.java:126)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
  1. missing thenReturn()
  2. you are trying to stub a final method, you naughty developer!
  3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

where line 126 is the first invocation of the mockWithValue method. 第126行是对mockWithValue方法的第一次调用。

So the question is: is there a way to reuse the same code in order to create many mocks with similar behavior? 所以问题是:是否有一种方法可以重用相同的代码以创建许多具有相似行为的模拟?

When it comes to some additional generics involvement while mocking it is better to go for the doReturn()..when() syntax: 当涉及到doReturn()..when()时涉及到其他泛型时,最好使用doReturn()..when()语法:

    doReturn(mockWithValue(JAXBElement.class, "a StringValue"))
        .when(result).getSomeStringValue();

    doReturn(mockWithValue(JAXBElement.class, 2))
        .when(result).getSomeIntegerValue();

and

    private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) {
        JAXBElement<T> mock = mock(jaxbElementClass);
        doReturn(value).when(mock).getValue();
        return mock;
    }

You should not mock while creating response. 创建响应时,您不应嘲笑。

Let me explain, in this code 让我解释一下这段代码

private <T> JAXBElement<T> mockWithValue(Class<JAXBElement> jaxbElementClass, T value) {
    JAXBElement<T> mock = mock(jaxbElementClass);
    when(mock.getValue()).thenReturn(value);
    return mock;
}

you are mocking JAXBElement<T> mock = mock(jaxbElementClass) and then you are using this complete method in return response. 您在JAXBElement<T> mock = mock(jaxbElementClass) ,然后在return响应中使用此完整方法。

You should first created these responses separately and then use them inside return . 您应该首先分别创建这些响应,然后在return使用它们。

String stringResponse=mockWithValue(JAXBElement.class, "a StringValue");
when(result.getSomeStringValue()).thenReturn(stringResponse);

Try this, it will work. 试试这个,它将起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM