【问题标题】:How do I mock local OAuth2RestTemplate restTemplate?如何模拟本地 OAuth2RestTemplate restTemplate?
【发布时间】:2020-02-07 01:59:50
【问题描述】:

我有一个方法:

public void putObj(Doc doc) {
        for (int i = 0; i < 3; i++) {
            try {
                OAuth2RestTemplate restTemplate = something.thatReturnsOAuth2RestTemplate(props);
                restTemplate.postForEntity(somethingElse.getUrl(), doc.toJSONString(), String.class);
                break;
            } catch (HttpClientErrorException | HttpServerErrorException e) {
                //do stuff in here
            }
        }
    }

还有我的测试课:

@RunWith(MockitoJUnitRunner.class)
@PrepareForTest(OkHttp3TemplateUtil.class)
public class TestingClass {

@InjectMocks
private static MyService myService;

@Mock
private static Something something;

@Mock
private static Props props;

@Mock
private static OAuth2RestTemplate restTemplate;

@Test
    public void testExceptionCaughtWhenThrownByRestTemplate(){
        PowerMockito.mockStatic(OkHttp3TemplateUtil.class);
        Doc doc = new Doc.docBuilder().setSomething("");

        when(something.thatReturnsOAuth2RestTemplate(props)).thenReturn(restTemplate);
        when(restTemplate.postForEntity("http://dummy.com", String.class, String.class)).thenThrow(HttpClientErrorException.class);
        myService.putObj(doc);
    }
}

无论我做什么,thenThrow 都不会抛出异常。在catch 之后,测试通过永远不会覆盖代码。我在这里错过了什么,我要疯了!

【问题讨论】:

    标签: java rest unit-testing testing mockito


    【解决方案1】:

    您似乎需要使用 Mockito 的匹配器。

    在您的情况下,restTemplate 的 3 个参数有点令人困惑。第一个是String 值,所以使用anyString() 匹配它并模拟出somethingElse.getUrl(),该代码不在示例中,所以不确定它的作用,但它必须返回String 而不是@987654326 @。看起来你想匹配第二个的任何字符串,如果不是 String ,你需要使用 Mockito 使用 anyString()any() 来完成此操作。第三个是String.class 的实际值,所以再次使用eq()。请注意,如果任何参数为空,它将不匹配。此外,如果您不小心,很容易最终模拟出不同的重载 postForEntity

    对于something.thatReturnsOAuth2RestTemplate,没有匹配器可能没问题。如果Props 类定义了equals,并且测试代码值和生产代码值相等。但是,该示例没有显示此信息,因此我也为此添加了any(Props.class)

    import static org.mockito.ArgumentMatchers.any;
    import static org.mockito.ArgumentMatchers.anyString;
    import static org.mockito.ArgumentMatchers.eq;
    
    @Test
        public void testExceptionCaughtWhenThrownByRestTemplate(){
            PowerMockito.mockStatic(OkHttp3TemplateUtil.class);
            Doc doc = new Doc.docBuilder().setSomething("");
    
                    when(something.thatReturnsOAuth2RestTemplate(any(Props.class))).thenReturn(restTemplate);
            when(restTemplate.postForEntity(anyString(), any(), eq(String.class))).thenReturn(response);
    }
    

    【讨论】:

    • 我得到与上面的代码完全相同的结果:(
    • OkHttp3TemplateUtil 是干什么用的?它没有出现在生产代码中
    • 抱歉,OkHttp3TemplateUtil = something。我在重命名方法以在此处发布时错过了它。
    • 如果somethingElse.getUrl()doc.toJSONString() 返回null 或不是String 的任何东西,例如URI,因为postForEntity 有很多重载,那么它将不匹配。
    • 这是我正在调用的postForEntity() 方法:public &lt;T&gt; ResponseEntity&lt;T&gt; postForEntity(URI url, @Nullable Object request, Class&lt;T&gt; responseType)
    猜你喜欢
    • 2019-12-21
    • 1970-01-01
    • 2018-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多