Reputation: 1863
I currently have a project using TestNG to execute tests against my Spring project. Within my project I have a set of Feign interfaces that handle external calls on my Eureka configuration. I am having difficulty understanding how to mock/intercept these calls on a test-by-test basis during execution.
Here is an example of one of my Feign interfaces:
@FeignClient ("http://my-service")
public interface MyServiceFeign {
@RequestMapping (value = "/endpoint/{key}", method = RequestMethod.GET)
SomePojo getByKey(@PathVariable ("key") String key);
}
I have a service that relies on the client:
@Service
public class MyService {
@Autowired
private MyServiceFeign theFeign;
public SomePojo doStuff() {
return theFeign.getByKey("SomeKey");
}
}
My tests are launched simply via:
@SpringBootTest (
classes = Service.class,
webEnvironment= SpringBootTest.WebEnvironment.RANDOM_PORT
)
@TestExecutionListeners (
inheritListeners = false,
listeners = {
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class
}
)
@DirtiesContext
@ContextConfiguration (initializers = CustomYamlLoader.class)
@ActiveProfiles ("test")
publi class MyModuleTest extends AbstractTestNGSpringContextTests {
// ....
}
What I want to do in my test is execute something like this:
@Test
public void doSomeTest() {
SomePojo fakeReturn = new SomePojo();
fakeReturn.setSomeStuff("some stuff");
/*
!!! do something with the injected feign for this test !!!
setupFeignReturn(feignIntercept, fakeReturn);
*/
SomePojo somePojo = injectedService.doStuff();
Assert.assertNotNull(somePojo, "How did I get NULL in a fake test?");
}
So, here's my dilemma: I am missing a key understanding to be able to do this, I think. That or I am completely missing the concept of how this should be handled. I don't think that using a fallback implementation makes sense here, but I could be wrong.
Help!
Upvotes: 3
Views: 671
Reputation: 3145
as far as I understand you are dealing with feign clients (and possibly ones with security on top, like basic auth or OAuth2), and want to do tests. But actually, the attend is not to test MyServiceFeign
is working, but MyService
is working properly, given the feign client retrieves a valid result.
For this purpose, you do not actually inject your feign client, you mock it.
In short, this can be achieved by two steps: using @MockBean
instead of @Autowired
and describe your clients behavior before you use it.
@RunWith(SpringRunner.class)
@SpringBootTest(classes = YourApp.class)
public class MyServiceUnitTest {
@MockBean
private MyServiceFeign myFeignClient;
@Autowiered
private MyService myService;
@Test
public void testSync() {
given(myFeignClient.getByKey("SomeKey")).willReturn(
new SomePojo("SomeKey")
);
assertEquals("SomeKey", myService.doStuff().getKey());
}
}
as already said, Mockito is used by spring for this way of testing components. I describe a more advanced setup with oauth2 intercepting and two ways of testing oauth2 intercepted feign clients.
Upvotes: 1