如何让一个方法在 junit 集成测试中什么都不做?
How to make a method do nothing in junit integration test?
我有一个邮件服务和控制器,我想一起测试,但我不想在测试 运行 时发送电子邮件。我尝试在测试 class 中对邮件发件人使用 @Autowire
使其成为方法 doNothing 但它失败了,因为它不是模拟。我真的不能把它变成 @Mock
因为我不是在调用控制器方法而是用 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
发出实际请求这里是 classes:
public class EmailControllerTest extends AbstractMvcTest {
private static final String CONTROLLER_URL = "/api/emails";
@Test
@Sql({DbScripts.EMAILS, DbScripts.IDENTITY_NUMBER_TYPES, DbScripts.SUBJECTS, DbScripts.USERS})
public void sendVerificationCodeToEmailStandardTest() throws Exception {
EmailWrapperDto dto = new EmailWrapperDto();
dto.setEmail("test@gmail.com");
MockHttpServletRequestBuilder request = put(CONTROLLER_URL + "/verify");
request.content(getRequestBodyFromObject(dto));
mockMvc.perform(request).andExpect(status().isOk());
}
}
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = EServicesWebBackendApplication.class)
@ActiveProfiles(ApplicationConstants.SPRING_PROFILE_TEST)
public abstract class AbstractMvcTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private ObjectMapper objectMapper;
private H2TestDatabaseCleaner dbCleaner = new H2TestDatabaseCleaner();
@Autowired
private SessionFactory sessionFactory;
protected MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = setupMockMvcBuilder(MockMvcBuilders.webAppContextSetup(webApplicationContext), true).build();
}
protected DefaultMockMvcBuilder setupMockMvcBuilder(DefaultMockMvcBuilder builder, boolean withCsrf) {
MockHttpServletRequestBuilder mockServletRequestBuilder = MockMvcRequestBuilders.get("/");
return builder.defaultRequest(mockServletRequestBuilder.contentType(MediaType.APPLICATION_JSON)
.header("X-Requested-With", "XMLHttpRequest"));
}
protected String getRequestBodyFromObject(Object objectToConvertToJson) throws JsonProcessingException {
return objectMapper.writeValueAsString(objectToConvertToJson);
}
@After
public void teardown() {
dbCleaner.clean(sessionFactory);
}
}
@Service
public class EmailService {
private static final int TWENTY_FOUR_HOURS_IN_MINUTES = 1440;
@Autowired
private MailSender mailSender;
@Autowired
private GenericRepository genericRepository;
@Transactional
public void sendVerificationCode(String email) {
User user = genericRepository.findByIdOrElseThrowException(User.class, 11);
String token = UUID.randomUUID().toString();
VerificationToken verificationToken = new VerificationToken();
verificationToken.setToken(token);
verificationToken.setUser(user);
verificationToken.setExpirationDate(calculateExpiryDate(TWENTY_FOUR_HOURS_IN_MINUTES));
genericRepository.save(verificationToken);
String subject = "Registration Confirmation";
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(email);
mailMessage.setFrom("test@gmail.com");
mailMessage.setSubject(subject);
mailMessage.setText(token);
mailSender.send(mailMessage);
}
private Date calculateExpiryDate(int expiryTimeInMinutes) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Timestamp(cal.getTime().getTime()));
cal.add(Calendar.MINUTE, expiryTimeInMinutes);
return new Date(cal.getTime().getTime());
}
}
如果您使用 spring 的 Mockito 功能,您应该能够像这样使用 @MockBean
注释:
public class EmailControllerTest extends AbstractMvcTest {
...
@MockBean
private MailSender mailSender;
...
}
然后定义(可选,什么都不做是 mockito 对 void 方法存根的默认行为)doNothing
操作:
Mockito.doNothing().when(mailSender).send(Mockito.any(SimpleMailMessage.class));
如果您想在模拟的 void 方法中使用 ArgumentCaptor
,这会很有用:
ArgumentCaptor<SimpleMailMessage> valueCapture = ArgumentCaptor.forClass(SimpleMailMessage.class);
Mockito.doNothing().when(mailSender)
.send(Mockito.any(SimpleMailMessage.class), valueCapture.capture());
参考:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html
https://www.baeldung.com/mockito-void-methods
我有一个邮件服务和控制器,我想一起测试,但我不想在测试 运行 时发送电子邮件。我尝试在测试 class 中对邮件发件人使用 @Autowire
使其成为方法 doNothing 但它失败了,因为它不是模拟。我真的不能把它变成 @Mock
因为我不是在调用控制器方法而是用 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
发出实际请求这里是 classes:
public class EmailControllerTest extends AbstractMvcTest {
private static final String CONTROLLER_URL = "/api/emails";
@Test
@Sql({DbScripts.EMAILS, DbScripts.IDENTITY_NUMBER_TYPES, DbScripts.SUBJECTS, DbScripts.USERS})
public void sendVerificationCodeToEmailStandardTest() throws Exception {
EmailWrapperDto dto = new EmailWrapperDto();
dto.setEmail("test@gmail.com");
MockHttpServletRequestBuilder request = put(CONTROLLER_URL + "/verify");
request.content(getRequestBodyFromObject(dto));
mockMvc.perform(request).andExpect(status().isOk());
}
}
@RunWith(SpringRunner.class)
@WebAppConfiguration
@SpringBootTest(classes = EServicesWebBackendApplication.class)
@ActiveProfiles(ApplicationConstants.SPRING_PROFILE_TEST)
public abstract class AbstractMvcTest {
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private ObjectMapper objectMapper;
private H2TestDatabaseCleaner dbCleaner = new H2TestDatabaseCleaner();
@Autowired
private SessionFactory sessionFactory;
protected MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = setupMockMvcBuilder(MockMvcBuilders.webAppContextSetup(webApplicationContext), true).build();
}
protected DefaultMockMvcBuilder setupMockMvcBuilder(DefaultMockMvcBuilder builder, boolean withCsrf) {
MockHttpServletRequestBuilder mockServletRequestBuilder = MockMvcRequestBuilders.get("/");
return builder.defaultRequest(mockServletRequestBuilder.contentType(MediaType.APPLICATION_JSON)
.header("X-Requested-With", "XMLHttpRequest"));
}
protected String getRequestBodyFromObject(Object objectToConvertToJson) throws JsonProcessingException {
return objectMapper.writeValueAsString(objectToConvertToJson);
}
@After
public void teardown() {
dbCleaner.clean(sessionFactory);
}
}
@Service
public class EmailService {
private static final int TWENTY_FOUR_HOURS_IN_MINUTES = 1440;
@Autowired
private MailSender mailSender;
@Autowired
private GenericRepository genericRepository;
@Transactional
public void sendVerificationCode(String email) {
User user = genericRepository.findByIdOrElseThrowException(User.class, 11);
String token = UUID.randomUUID().toString();
VerificationToken verificationToken = new VerificationToken();
verificationToken.setToken(token);
verificationToken.setUser(user);
verificationToken.setExpirationDate(calculateExpiryDate(TWENTY_FOUR_HOURS_IN_MINUTES));
genericRepository.save(verificationToken);
String subject = "Registration Confirmation";
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setTo(email);
mailMessage.setFrom("test@gmail.com");
mailMessage.setSubject(subject);
mailMessage.setText(token);
mailSender.send(mailMessage);
}
private Date calculateExpiryDate(int expiryTimeInMinutes) {
Calendar cal = Calendar.getInstance();
cal.setTime(new Timestamp(cal.getTime().getTime()));
cal.add(Calendar.MINUTE, expiryTimeInMinutes);
return new Date(cal.getTime().getTime());
}
}
如果您使用 spring 的 Mockito 功能,您应该能够像这样使用 @MockBean
注释:
public class EmailControllerTest extends AbstractMvcTest {
...
@MockBean
private MailSender mailSender;
...
}
然后定义(可选,什么都不做是 mockito 对 void 方法存根的默认行为)doNothing
操作:
Mockito.doNothing().when(mailSender).send(Mockito.any(SimpleMailMessage.class));
如果您想在模拟的 void 方法中使用 ArgumentCaptor
,这会很有用:
ArgumentCaptor<SimpleMailMessage> valueCapture = ArgumentCaptor.forClass(SimpleMailMessage.class);
Mockito.doNothing().when(mailSender)
.send(Mockito.any(SimpleMailMessage.class), valueCapture.capture());
参考:https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/mock/mockito/MockBean.html
https://www.baeldung.com/mockito-void-methods