java - 在 Spring Boot 中的 mockito 测试中的 if...else 语句问题
问题描述
如何为 if...else 语句编写一个模拟测试用例,其中还包括异常测试,我对此感到很困惑。UserService 是一个接口
用户工厂.java
public class UserFactory {
@Autowired
private List<UserService> UserList;
private final Map<String, UserService> UserMap = new HashMap<>();
@PostConstruct
public void initUserMap() {
for (final UserService user : UserList) {
UserMap.put(user.getUserId(), user);
}
}
public UserService getUser(String userId) {
final UserService userService = UserMap.get(userlId);
if (null == userService) {
throw new IllegalArgumentException("user are not in the group");
}
return userService;
}
}
用户服务(接口)
public interface UserService{
String getUserName();
String getUserId();
}
这是我的测试,但它不正确......
@RunWith(MockitoJUnitRunner.class)
public class UserServiceTest {
@Mock
private UserService userService;
@InjectMocks
private UserFactory UserFactory;
private Map<String, User> UserMap;
private String userId = "123";
@Before
public void set_up(){
UserMap = new HashMap<>();
UserMap.put(userId, userService);
}
@Test
public void getUser(){
when(UserMap.get(userId)).thenReturn(userService);
userService actual = userServiceFactory.getUser(userId);
assertEquals(UserMap.get(userId), actual);
}
}
解决方案
1)您编写单元测试,而不是切片测试或集成测试。所以这里 Spring Boot 无关紧要,因为您不需要加载容器来测试组件的逻辑。如果您有兴趣,
可以阅读我关于该领域的问题/答案。
2)逻辑中的分支(if/else
)意味着您有多个场景。
不同的场景通常意味着不同的测试方法和有意义的名称。
您还可以依赖给定/何时/那么成语。
3)由于在您的测试中,分支的输入信息由模拟提供,这也意味着您将在每个测试方法中为模拟注册不同的行为。
4)UserService
不需要被嘲笑。它必须是模拟返回的值,而不是模拟本身。在这里你必须模拟Map
.
5)你测试UserFactory
,所以你必须命名它UserFactoryTest
。
例如 :
@RunWith(MockitoJUnitRunner.class)
public class UserFactoryTest {
@Mock
private Map<String, User> UserMap;
@InjectMocks
private UserFactory UserFactory;
private String userId = "123";
@Test
public void getUser(){
when(UserMap.get(userId)).thenReturn(userService);
userService actual = userServiceFactory.getUser(userId);
assertEquals(UserMap.get(userId), actual);
}
@Test
public void getUser_with_unknown_userId(){
Assertions.assertThrows(IllegalArgumentException.class,
()-> userServiceFactory.getUser(userId));
}
}
您注意到在第二种情况下,我没有为模拟注册任何行为。
默认情况下,Mockito 将返回null
,实际上这是我引发异常所需要的。所以没关系。
另请注意,我通过依赖 JUnit 5 库而不是您似乎根据使用的跑步者使用的 JUnit 4 库来编写断言。
您应该考虑切换到 JUnit 5 进行新测试。
推荐阅读
- amazon-redshift - 在作为保留关键字的 Redshift COPY 命令中使用列名
- twilio - 在 Twilio Video iOS SDK 中指定房间类型
- php - 如何获取两个值以在 php 和 ajax 中获取结果
- amazon-web-services - AWS 负载均衡器将流量路由到具有多个微服务的目标组
- sql-server - 在 WHERE 子句中对 GUID 使用 LIKE 会导致全表扫描
- python - Python OpenCV matchTemplate with Masking - 在所有位置找到匹配项
- php - 使用单个 Laravel 代码库管理多个网站
- javascript - 未捕获的不变违规:目标容器不是 Object.render 的 DOM 元素
- java - 如何从 Google GeoApiContext 的私钥创建加密密钥?
- if-statement - 如何使用条件格式将单元格颜色设置为等于另一个单元格颜色?