【问题标题】:Mockito not working for RestTemplateMockito 不适用于 RestTemplate
【发布时间】:2017-05-22 04:59:48
【问题描述】:

我正在使用 mockito 来模拟 RestTemplate 交换调用。以下是我使用过的,但它没有选择模拟的 RestTemplate。

模拟调用。

ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class, userId);

模拟的 RestTempate 如下。

Mockito.when(restTemplate.exchange(
            Matchers.anyString(),
            Matchers.any(HttpMethod.class),
            Matchers.<HttpEntity<?>> any(),
            Matchers.<Class<String>> any(),
            Matchers.anyString())).
            thenReturn(responseEntity);

知道这里出了什么问题吗?这与 @RunWith(PowerMockRunner.class) 一起运行,因为我正在模拟静态内容。

【问题讨论】:

  • @RC。也尝试使用 Matchers.anyVararg()。仍然没有接听模拟电话。
  • 然后,我收到重载解析失败错误。不能'编译代码。 (对交换的引用不明确)因为所有参数都相同,并且只有最后一个参数是对象 var arg 和 Map?
  • 试试这个exchange(anyString(), any(), any(), Mockito.&lt;Class&lt;?&gt;&gt; any(), anyString())
  • 确保在执行 SUT 之前必须调用 Mockito.when

标签: java mockito resttemplate


【解决方案1】:

signature 的最后一个参数是Object...,所以你必须使用anyVarArg()。这在这里工作正常:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(MockitoJUnitRunner.class)
public class Foo {
    @Mock
    private RestTemplate restTemplate;

    @Test
    public void testXXX() throws Exception {
        Mockito.when(this.restTemplate.exchange(Matchers.anyString(), Matchers.any(HttpMethod.class), Matchers.any(), Matchers.<Class<String>>any(), Matchers.<Object>anyVararg()))
               .thenReturn(ResponseEntity.ok("foo"));

        final Bar bar = new Bar(this.restTemplate);
        assertThat(bar.foobar()).isEqualTo("foo");
    }

    class Bar {
        private final RestTemplate restTemplate;

        Bar(final RestTemplate restTemplate) {
            this.restTemplate = restTemplate;
        }

        public String foobar() {
            final ResponseEntity<String> exchange = this.restTemplate.exchange("ffi", HttpMethod.GET, HttpEntity.EMPTY, String.class, 1, 2, 3);
            return exchange.getBody();
        }
    }
}

注意:使用anyVarArg,也可以强制转换(Object) Matches.anyVarArgs(),避免模棱两可的方法错误。

【讨论】:

  • 似乎我发现了问题,我在方法内创建了一个新的 RestTemplate 对象,(在你的情况下是在 foobar 方法内)。所以它不会与模拟的 RestTemplate 对象绑定并通过实际路径执行。
  • @user180100 如果我有@Value "${baseurl:}") private String baseUrl;在 Bar 内部,创建 new Bar() 会使所有局部变量为空吗?
【解决方案2】:

因为我在我的方法中执行以下操作。模拟的交换方法没有绑定。

RestTempate restTempalte = new RestTemplate();

所以我将我的源代码更改为以下,并创建一个方法来创建一个 RestTempate 实例。

public RestTemplate createRestTemplate() {
    return new RestTemplate();
}

并在测试源中做了以下操作。

@Before
public void createMyClass() {
    MockitoAnnotations.initMocks(this);

    sampleClient = new SampleClient() { 
        @Override
        public RestTemplate createRestTemplate() {
            return restTemplate;
        }
    };
}

【讨论】:

    【解决方案3】:

    我在同样的问题上苦苦挣扎。这是一个对我有用的模拟。

     when(this.restTemplate.exchange(anyString(),
                any(),
                any(),
                eq(String.class),
                anyString()))
                .thenReturn(new ResponseEntity<>(subscriptionDataJson,
                        HttpStatus.OK));
    

    请注意,我将可变参数用作 anyString()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-07
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 2022-10-13
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多