我已经实现了一个基于这个官方存储库调用getapi的假客户机。我有一节规则课 UserValidationRule
需要调用get api调用 getUser()
验证一些东西。这和预期的一样有效,但是当我开始测试这个规则类时,模仿外部客户机并不成功,它会继续调用实际的api。我已经简化了情况,所以请忽略简单lol。这是一个后续问题,我发现这个问题
api返回此模型:
@Data
public class userModel {
private long id;
private String name;
private int age;
}
与rest客户端方法的接口:
public interface UserServiceClient {
@RequestLine("GET /users/{id}")
UserModel getUser(@Param("id") int id);
}
在rule类中,我构建了假客户端并调用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);
}
}
接下来是测试课:
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;
}
}
当我调试时 validateWhenAgeIsNotBlank()
,我看到usermodel不是在test类中生成的,并且值都是null。如果我通过一个真实的 userId
,我得到了数据库中的实际用户模型。
我想问题是 UserServiceClient
不是被嘲笑。这个 verify
就像上面说的 getUser()
未调用。这可能与在 UserValidationRule
使用feign.builder()。。。请纠正我,如果我错了,告诉我我错过了什么或任何建议,如何嘲笑它正确。
1条答案
按热度按时间gpnt7bae1#
您没有使用Spring
UserServiceClient
豆子。每次你打电话UserValidationRule.validate
它叫validateUser
这又称为getServiceClient
方法。这个getServiceClient
创建的新示例UserServiceClient
每次调用。这意味着在测试模拟的UserServiceClient
根本不用。我将重组代码如下;
先声明
UserServiceClient
作为最终的@RequiredArgsConstructor
或替换@RequiredArgsConstructor
与@AllArgsConstructor
. 此更改的目的是允许UserServiceClient
而不是在服务方法内部创建。那就单独谈谈
Configuration
作为Springbean构建外部客户机的类;在运行时,这个bean现在将被注入到
UserValidationRule
.至于单元测试更改,您正在正确地创建mock,但是没有在任何地方设置/注入该mock。你要么用
@Mock
以及@InjectMocks
注解或手动创建的示例UserValidationRule
在你的@Before
方法。这里是如何
@Mock
以及@InjectMocks
使用应该像;或继续使用
mock(...)
方法并手动创建UserValidationRule
.这将确保您在运行时使用spring管理的外部客户机bean的单个示例和模拟示例进行测试。