FeignClient分流测试环境

背景

因为写了个分流,需要做UT,所以研究一下怎么在代码里面仿照假的下游服务器。

Service

声明服务端FirstFakeMessagingRestService。

@RestController
@RequestMapping(path = "/messaging")
public class FirstFakeMessagingRestService {

    @GetMapping(params = {"name"}, produces = "application/json")
    public String getMessage(@RequestParam("name") final String name) {
        assertThat(name).isEqualTo("Foo");
        return "{\"text\":\"Hello, Foo\"}";
    }
}

实现服务端2,因为不能映射到同一个path,所以修改一下path。

@RestController
@RequestMapping(path = "/messaging2")
public class SecondFakeMessagingRestService {

    @GetMapping(params = {"name"}, produces = "application/json")
    public String getMessage(@RequestParam("name") final String name) {
        assertThat(name).isEqualTo("Foo");
        return "{\"text\":\"Hello, Bar\"}";
    }
}

Message类,用于传递。

@Getter
@Setter
public class Message {
    private String text;
}

Ribbon

做个Fake Ribbon 配置,返回本地的ip端口。

@Configuration
public class FakeRibbonConfiguration {

    @LocalServerPort
    int port;

    @Bean
    public ServerList<Server> serverList() {
        return new StaticServerList<>(new Server("localhost", port));
    }
}

Client

service注册到ribbon上:firstMessagingRestClient & secondMessagingRestClient,使用上面的FakeRibbonConfiguration。

@Configuration
//@EnableFeignClients(clients = MessagingRestClient.class)
@EnableFeignClients
@EnableAutoConfiguration
@RibbonClient(name = "firstMessagingRestClient",configuration = FakeRibbonConfiguration.class)
public class FirstFakeFeignConfiguration {}
@Configuration
public class RestTemplateConfiguration {
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }
}
@Configuration
//@EnableFeignClients(clients = MessagingRestClient.class)
@EnableFeignClients
@EnableAutoConfiguration
@RibbonClient(name = "secondMessagingRestClient",configuration = FakeRibbonConfiguration.class)
public class SecondFakeFeignConfiguration {}

FeignClient

声明FeignClient:

@FeignClient(name = "firstMessagingRestClient", path = "/messaging")
public interface MessagingRestClient {

    @GetMapping(params = {"name"})
    Message getMessage(@RequestParam("name") final String name);

    @PostMapping(params = {"name"})
    Message setMessage(@RequestParam("name") final String name, @RequestBody final Message message);
}

application

@LcloudSpringBootApplication
//@LcloudEnableFeignClients
//@EnableFeignClients
@LcloudEnableFeignClients
//@LcloudEnableMonitor
@LcloudEnableZuulProxy
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

ut

@RunWith(SpringJUnit4ClassRunner.class)
@PropertySources({ @PropertySource("classpath:bootstrap.properties"),
        @PropertySource("classpath:esg.properties") })
@SpringBootTest(
        classes = {
                Application.class
        }
        ,
        webEnvironment =  SpringBootTest.WebEnvironment.DEFINED_PORT
//        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@ContextConfiguration(
        classes = {RestTemplateConfiguration.class})
public class GreyReleaseTests {
    private static final Logger logger = LoggerFactory.getLogger(GreyReleaseTests.class.getName());

    @Autowired
    MessagingRestClient client;

    @LocalServerPort
    int port;

    @Autowired
    @Qualifier(value = "grayReleaseOkHttpClient")
    private OkHttpClient okHttpClient;

    @Test
    public void testFeignClientRequest() {
        Map<String, Integer> result = new HashMap<>();
        for(int i = 0;i < 100;++i){
            Message response = client.getMessage("Foo");
            result.put(response.getText(), result.getOrDefault(response.getText(), 0) + 1);
        }
        double ratio = result.containsKey("Hello, Bar") ?
                (double)result.get("Hello, Foo")/result.get("Hello, Bar") : 0.0;
        logger.info("testFeignClientRequest ratio = {}", ratio);
        Assert.assertTrue(ratio > 0.7);
        Assert.assertTrue(ratio < 1.3);
    }

    @Test
    public void testOkHttpClientRequest() throws IOException {
        String url = "http://localhost:8008/messaging?name=Foo";
        Map<String, Integer> result = new HashMap<>();
        for(int i = 0;i < 100;++i){
            Request request = new Request.Builder().url(url).get().build();
            Response response = okHttpClient.newCall(request).execute();
            String responseStr = response.body().string();
            result.put(responseStr, result.getOrDefault(responseStr, 0) + 1);
        }
        double ratio = (double)result.get("{\"text\":\"Hello, Foo\"}")/result.get("{\"text\":\"Hello, Bar\"}");
        logger.info("testOkHttpClientRequest ratio = {}", ratio);
        Assert.assertTrue(ratio > 0.7);
        Assert.assertTrue(ratio < 1.3);
    }
}

refer

https://codeburst.io/unit-testing-feignclient-using-restcontroller-and-ribbonclient-4e76bfeddf41

comments powered by Disqus