java - 如何使用 Mockito 模拟 feign.Client.Default

标签 java jersey mockito dropwizard netflix-feign

我正在写一个 Dropwizard应用和使用 Feign用于构建对外部服务的客户端调用。我有自定义编码器和解码器,我正在注册 feign.Builder像这样:

    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.Client.Default.execute 的调用所以当它提出请求时它会返回我的假响应 this call site .该模拟的示例如下:

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
}

没运气。 Cleint.Default当我到达 call site 时,类不会被 mock 对于代码中的请求。我究竟做错了什么?

最佳答案

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

这比听起来容易:

MyService.Java

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
@FeignClient("target-service")
public interface MyFeignClient{

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

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

MyFeignClientMock.java
@Component
public class MyFeignClientMock implements MyFeignClient {

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

MyServiceTest.java
@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...
}

关于java - 如何使用 Mockito 模拟 feign.Client.Default,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33005166/

相关文章:

java - Mockito 中的条件 stub 给定多个方法的调用顺序

java - 如何为原始类型创建 Mockito ArgumentCaptor?

java - 无法将 Spring Security BASIC 身份验证集成到 Jersey/JAX-RS 和 Tomcat 中

java - 泛型的 .class 语法中断

java - 线程 "main"异常 java.lang.UnsatisfiedLinkError : . ..\jzmq.dll: 找不到依赖库

java - 将 KeyEvent 传递给不同的组件

java - GrizzlyServerFactory.createHttpServer 和 new GrizzlyWebServer WebServer 的区别

java - 我在这个 Jersey Java 类中做错了什么?

java - 模拟 Vertx.io 异步处理程序

java - 使用 Jedis 在单个管道中进行多个 Redis 事务(多/执行)