java之Spring Boot 中的单元测试或集成测试
我在 Spring Boot
中查看了与测试相关的各种在线教程并且对测试的引用方式感到困惑。
一些文章引用了使用 @WebMvcTest
的 Controller 测试注释为 Unit Test
而有些人将其称为 Integration Test
.不确定哪一个是正确的。
相同的问题适用于 @DataJpaTest
的存储库层测试.
我在我的应用程序中编写了以下两个测试,一个用于 Controller ,另一个用于存储库。
在底部,我对两者都有一些疑问。请指导。
UserControllerTest.java
@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private UserRepository userRepository;
@Test
public void signUp() throws Exception {
this.mockMvc.perform(get("/signup")).andExpect(status().isOk());
}
}
UserRepositoryTest.java
@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository userRepository;
@Test
public void whenFindByName_thenReturnEmployee() {
// given
User u = new User();
u.setName("ab");
u.setEmail("ab@cd.com");
entityManager.persistAndFlush(u);
// when
Optional<User> user = userRepository.findById(1L);
// then
assertTrue(user.isPresent());
}
}
我的问题是:
@WebMvcTest, @DataJpaTest
或 @SpringBootTest
确定测试类型( Unit
或 Integration
)还是使用 @MockBean
在测试中,它决定了吗? UserControllerTest.java
是我们模拟的单元测试 userRepository
此处依赖 @MockBean private UserRepository userRepository
而在 UserRepositoryTest.java
我们正在使用 @Autowired private UserRepository userRepository
Autowiring 它.为什么 ?? 请您参考如下方法:
为什么需要spring来做单元测试?您只能使用 Mockito 来执行此操作,而无需启动 spring 上下文。这在此处详细解释和讨论:https://reflectoring.io/unit-testing-spring-boot/
在使用@MockBean 时,我也很困惑!这被认为是单元测试还是集成测试?
在我看来,即使我们使用的是模拟 bean,但我们仍然在 spring 上下文中运行,对我来说这是一个集成测试(因为单元测试不需要任何 spring 上下文来运行)。 Brandon 提到的同一站点将 @MockBean 视为集成测试 https://www.baeldung.com/java-spring-mockito-mock-mockbean .
Image from above site
Brandon 回应:“集成测试不应该包含任何模拟,两种类型的测试都应该单独运行。”
如果你想测试一个从 Controller 开始一直到数据库的 api,但又想排除其他系统(比如 kafka 或外部微服务)怎么办?你将如何实现这一目标?你肯定需要@MockBean。这是一个集成测试,即使它模拟了 bean。
总而言之(根据我的经验以及在搜索和阅读了很多天的矛盾信息之后)。这是我的意见:
即使您使用@MockBean,也可以进行集成测试。这方面的一个例子:
如果我们想从 Controller 开始测试一个 api 一直到
数据库,但我们想排除其他系统(如 kafka、电子邮件或
其他外部微服务)。我们将如何实现这一目标?我们
绝对需要@MockBean。这是一个集成测试,即使它
使用一些模拟 bean 。
意思是调用 api 并确保它返回正确的
状态代码和响应格式)。这被认为是单元测试还是
集成测试?它不是一个单元,因为单元测试不需要 spring
要在其中运行的上下文。它实际上是介于 unit 和
集成测试。这个来源很好地解释了这个概念
https://blog.marcnuri.com/mockmvc-spring-mvc-framework/ (更具体地说是 MockMvc 独立设置)所以我认为,
然后返回到团队在哪里放置这些测试(在单元中
test 文件夹,在集成测试文件夹中,在一个单独的文件夹中?)
还需要使用良好的命名约定来避免任何
与纯单元测试或纯集成测试混淆
类(class)。据我所知,大多数团队都会考虑这些单元测试,但我
我不确定这是否是最佳做法!
//unit test to call an api using MockMvc and mockito only
@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
private MockMvc mockMvc;
@Mock
UserService userService;
@InjectMocks
UserController controllerUnderTest;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(controllerUnderTest).build();
}
@Test
public void testGetUser() throws Exception {
//given:
when(userService.getUser(.......)).thenReturn(....);
//when:
String url = "http://localhost:8081/api/ ....your url";
//then:
this.mockMvc.perform(get(url)).andDo(print()).andExpect(status().isOk());
}
}
希望有所帮助,如果有更好的意见,请告诉我,因为我为此苦苦挣扎:)
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。