首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Mockito模拟feign.Client.Default

如何使用Mockito模拟feign.Client.Default
EN

Stack Overflow用户
提问于 2015-10-08 09:33:11
回答 2查看 15.6K关注 0票数 3

我正在编写一个Dropwizard应用程序,并使用Feign来构建对外部服务的客户端调用。我有自定义的编码器和解码器,我正在向feign.Builder注册,如下所示:

代码语言:javascript
复制
    this.feignBuilder = Feign.builder()
            .contract(new JAXRSContract()) // we want JAX-RS annotations
            .encoder(new JacksonEncoder()) // same as what dropwizard is using
            .decoder(new CustomDecoder())
            .errorDecoder(new CustomErrorDecoder())
            .requestInterceptor(new AuthKeyInterceptor(config.getInterceptor()));

我正在为feign客户端调用编写单元测试,这样我就可以观察feign机制如何处理我的编码器/解码器覆盖和异常上的气泡。我现在对用假服务器编写集成测试不感兴趣(这是我看到的人们为这种情况编写的最常见的测试类型)。

这应该是直接的。我想模拟feign发出请求的那一点,并让它返回我的假响应。这意味着我应该模拟对feign.Client.Default.execute的调用,这样当它将请求作为this call site时,它将返回我的假响应。这是一个模拟的例子:

代码语言:javascript
复制
String responseMessage = "{\"error\":\"bad\",\"desc\":\"blah\"}";
feign.Response feignResponse = FeignFakeResponseHelper.createFakeResponse(404,"Bad Request",responseMessage);
Client.Default mockFeignClient = mock(Client.Default.class);
try {
     when(mockFeignClient.execute(any(feign.Request.class),any(Request.Options.class))).thenReturn(feignResponse);
} catch (IOException e) {
     assertThat(true).isFalse(); // fail nicely
}

不走运。当我到达代码中请求的call site时,Cleint.Default类不会被模拟。我做错了什么?

EN

回答 2

Stack Overflow用户

发布于 2016-03-27 14:54:27

如前所述,Mockito的功能还不够强大。我用一个手动模拟解决了这个问题。

它比听起来更简单:

MyService.Java

代码语言:javascript
复制
public class MyService{
    //My service stuff      

    private MyFeignClient myFeignClient;

    @Inject //this will work only with constructor injection
    public MyService(MyFeignClient myFeignClient){
        this.MyFeignClient = myFeignClient
    }


    public void myMethod(){
        myFeignClient.remoteMethod(); // We want to mock this method
    }
}

MyFeignClient.Java

代码语言:javascript
复制
@FeignClient("target-service")
public interface MyFeignClient{

    @RequestMapping(value = "/test" method = RequestMethod.GET)
    public void remotemethod();
}

如果您想在模拟feignclient的同时测试上面的代码,请执行以下操作:

MyFeignClientMock.java

代码语言:javascript
复制
@Component
public class MyFeignClientMock implements MyFeignClient {

    public void remoteMethod(){
         System.out.println("Mocked remoteMethod() succesfuly");
    }
}

MyServiceTest.java

代码语言:javascript
复制
@RunWith(SpringJUnit4ClassRunner.class)
public class MyServiceTest {

    private MyService myService;

    @Inject
    private MyFeignClientMock myFeignClientMock;

    @Before
    public void setUp(){
       this.myService = new MyService(myFeignClientMock); //inject the mock
    }

    //Do tests normally here...
}
票数 3
EN

Stack Overflow用户

发布于 2015-10-10 00:40:14

事实证明,Mockito的功能还不够强大,无法完成我认为它能做的事情。正确的解决方案是使用PowerMockito模拟构造函数,以便Client.Default在包含该引用的类中实例化时返回模拟的实例。

在经历了许多编译错误的痛苦之后,我让PowerMockito进行了编译,看起来它可以工作了。遗憾的是,它没有返回我的mock,调用仍在进行中。我过去尝试过PowerMockito,但由于它带来的额外问题,我从未抽出时间使用它。因此,我仍然认为,仅仅是即插即用并不是非常容易的。

很遗憾,尝试做这样的事情是如此之难。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33005166

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档