Java 如何使用Mockito模拟feign.Client.Default
我正在编写一个Java 如何使用Mockito模拟feign.Client.Default,java,jersey,mockito,dropwizard,netflix-feign,Java,Jersey,Mockito,Dropwizard,Netflix Feign,我正在编写一个Dropwizard应用程序,并使用Feign来建立对外部服务的客户端调用。我在feign.Builder注册了自定义编码器和解码器,如下所示: this.feignBuilder=Feign.builder() .contract(新的jaxrcontract())//我们需要JAX-RS注释 .encoder(新JacksonEncoder())//与dropwizard使用的相同 .decoder(新的CustomDecoder()) .errorDecoder(新的Cust
Dropwizard
应用程序,并使用Feign
来建立对外部服务的客户端调用。我在feign.Builder
注册了自定义编码器和解码器,如下所示:
this.feignBuilder=Feign.builder()
.contract(新的jaxrcontract())//我们需要JAX-RS注释
.encoder(新JacksonEncoder())//与dropwizard使用的相同
.decoder(新的CustomDecoder())
.errorDecoder(新的CustomErrorDecoder())
.requestInterceptor(新的AuthKeyInterceptor(config.getInterceptor());
我正在为feign
客户端调用编写单元测试,这样我就可以观察feign机器如何处理编码器/解码器覆盖和异常气泡。我现在对用假服务器编写集成测试不感兴趣(这是我看到人们为这种情况编写的最常见的测试类型)
这应该是直截了当的。我想模拟feign
发出请求的点,让它返回我的假响应。这意味着我应该模拟调用feign.Client.Default.execute
,以便在发出请求时返回我的假响应。该模拟的示例如下:
String responseMessage=“{\'error\”:\“bad\”,\“desc\”:\“blah\”}”;
feign.Response feignResponse=FeignFakeResponseHelper.createFakeResponse(404,“错误请求”,responseMessage);
Client.Default mockFeignClient=mock(Client.Default.class);
试一试{
当(mockFeignClient.execute)(any(feign.Request.class)、any(Request.Options.class))。然后返回(feignResponse);
}捕获(IOE异常){
assertThat(true).isFalse();//很好地失败
}
不走运。当我在代码中找到请求时,
Cleint.Default
类不会被模拟。我做错了什么?事实证明,Mockito
的功能不足以完成我认为它可以完成的事情。正确的解决方案是模拟构造函数,因此Client.Default
会在包含该引用的类中实例化模拟实例时返回该实例
在经历了大量的编译错误之后,我得到了PowerMockito
进行编译,而且它似乎可以正常工作。唉,它没能返回我的模拟,呼叫仍在进行。我过去曾尝试过PowerMockito
,但由于它带来了额外的问题,我从未使用过它。所以我仍然认为,即插即用并不是一件超级容易的事
很遗憾,尝试做这样的事情太难了。如前所述,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
}
}
@FeignClient("target-service")
public interface MyFeignClient{
@RequestMapping(value = "/test" method = RequestMethod.GET)
public void remotemethod();
}
@Component
public class MyFeignClientMock implements MyFeignClient {
public void remoteMethod(){
System.out.println("Mocked remoteMethod() succesfuly");
}
}
@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...
}
MyFeignClient.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
}
}
@FeignClient("target-service")
public interface MyFeignClient{
@RequestMapping(value = "/test" method = RequestMethod.GET)
public void remotemethod();
}
@Component
public class MyFeignClientMock implements MyFeignClient {
public void remoteMethod(){
System.out.println("Mocked remoteMethod() succesfuly");
}
}
@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...
}
如果要在模拟假客户端的同时测试上述代码,请执行以下操作:
MyFeignClientMock.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
}
}
@FeignClient("target-service")
public interface MyFeignClient{
@RequestMapping(value = "/test" method = RequestMethod.GET)
public void remotemethod();
}
@Component
public class MyFeignClientMock implements MyFeignClient {
public void remoteMethod(){
System.out.println("Mocked remoteMethod() succesfuly");
}
}
@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...
}
MyServiceTest.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
}
}
@FeignClient("target-service")
public interface MyFeignClient{
@RequestMapping(value = "/test" method = RequestMethod.GET)
public void remotemethod();
}
@Component
public class MyFeignClientMock implements MyFeignClient {
public void remoteMethod(){
System.out.println("Mocked remoteMethod() succesfuly");
}
}
@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...
}