I've implemented a feign client that calls a get API based on this official repository. I have a rule class UserValidationRule
that needs to call that get API call getUser()
and validate some stuff. That works as expected but when I get to testing that rule class, mocking the feign client is not successful and it continues to call the actual API. I've simplified the situation so please ignore the simplicity lol. This is a follow up question I have after i found this stackoverflow question
The API returns this model:
@Data
public class userModel {
private long id;
private String name;
private int age;
}
The interface with the rest client method:
public interface UserServiceClient {
@RequestLine("GET /users/{id}")
UserModel getUser(@Param("id") int id);
}
And in the rule class, i build the feign client and call the API:
@RequiredArgsConstructor
@Component
public class UserValidationRule {
private static final String API_PATH = "http://localhost:8080";
private UserServiceClient userServiceClient;
public void validate(String userId, ...) {
// some validations
validateUser(userId);
}
private void validateUser(String userId) {
userServiceClient = getServiceClient();
UserModel userModel = userServiceClient.gerUser(userId);
// validate the user logic
}
}
private UserServiceClient getServiceClient() {
return Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.target(UserServiceClient.class, API_PATH);
}
}
And here comes the test class:
public class UserValidationRuleTest {
private UserServiceClient userServiceClient = mock(UserServiceClient.class);
private UserValidationRule validationRule = new UserValidationRule();
private UserModel userModel;
@Before
public void init() {
userModel = generateUserModel();
}
@Test
public void validateWhenAgeIsNotBlank() {
doReturn(userModel).when(userServiceClient).getUser(any());
validationRule.validate("123", ...);
// some logic ...
assertEquals(.....);
verify(userServiceClient).getUser(any());
}
private UserModel generateUserModel() {
UserModel userModel = new UserModel();
userModel.setName("Cody");
userModel.setAge("22");
return accountModel;
}
}
As I debug validateWhenAgeIsNotBlank()
, i see that the userModel is not the one that's generated in the test class and the values are all null. If I pass in an actual userId
, i get an actual UserModel that I have in my db.
I think the problem is that UserServiceClient
is not being mocked. The verify
is failing as it says the getUser()
is not invoked. It might be something to do with how the feign client is declared in the UserValidationRule
with the feign.builder()...
Please correct me if I'm wrong and tell me what I'm missing or any suggestions on how to mock it correctly.