Since upgrading to Spring Cloud Netflix Core 1.1.0 RC2 from M5 my tests fail. This is because the FeignClient bean is marked as primary. In my tests I use a mock client interface which I mark as @Primary in my test to override the FeignClient, so I can mock the feignclient during testing.
This is now broken since the @FeignClient bean is marked as primary in the FeignClientRegistar. Since I do not know a workaround, I would like to "opt-in" on the primary option of the FeignClient instead that this is mandatory.
A possibility is to start your tests with a profile ("test" for example) and tell the @Configuration class which has the @EnableFeignClient annotation on it, that it should not be used in test profile (@Profile("!test"))
Then the FeignClient beans aren't even created.
Thank you for the workaround. We do something like that now (using Spring Boot Conditionals), but we want to set all the "@Enable...." annotations on our main Spring Boot application configuration class, so that we have one location for all our microservices to see what technology we have configured.
As mentioned in #1085 we could only set the bean as primary if there is a fallback. That would help mocking feign clients that have fallbacks, though.
Maybe it could be done with properties that tests could set?
You can exclude the configuration that has @EnableFeignClient on it from the component scan, this will prevent the FeignClient Bean from being created and you can create your own mock bean.
@Configuration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Application.class),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = FeignClientConfig.class)}
)
public class TestApplication {
@Bean()
@Primary()
public FeignClient feignClient() {
return new FeignClientMock();
}
}
Could it still be possible to remove the @Primary in the feignClients. This blocks the option to decorate any feignclient
It would be great if the @FeignClient annotation had a boolean primary() default true; so we could readily opt-out of this behaviour when required.
We have a use-case of implementing the @FeignClient annotated interface with a cacheing facade we mark with @Primary that no longer works without having to qualify.
Wouldn't it be better to anotate FeignClients with @Priority or @Order with some convinient value? This way It would be easier to Mock/extend. We could set higher priority on our Mocks. @Primary doesn't really adhere to open-closed principle in my opinion.
Wouldn't it be better to anotate FeignClients with
@Priorityor@Orderwith some convinient value? This way It would be easier to Mock/extend. We could set higher priority on our Mocks.@Primarydoesn't really adhere to open-closed principle in my opinion.
Actually you can now disable primary of a FeignClient: https://cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-feign.html#_feign_and_literal_primary_literal
I'm not sure if this will work in your case. I learned to love Wiremock for testing my code including FeignClient calls, so for me primary makes no problem now.
Most helpful comment
A possibility is to start your tests with a profile ("test" for example) and tell the
@Configurationclass which has the@EnableFeignClientannotation on it, that it should not be used in test profile (@Profile("!test"))Then the FeignClient beans aren't even created.