我对spring有些意见 LocaleContextHolder
.
我有以下代码:
public void sendPasswordRecoverySmsAsync(String phone) {
CompletableFuture.runAsync(() -> {
sendPasswordRecoverySmsSync(phone);
});
}
public void sendPasswordRecoverySmsSync(String phone) {
User user = userDao.findByPhone(phone, User.class).orElseThrow(() -> new UserNotFoundException(phone));
log.info("User found, recovering password");
user.setUpdateTime(LocalDateTime.now());
userDao.save(user);
int otp = codesGenerator.generateOtp(user.getUpdateTime());
// Sends the SMS.
Locale locale = LocaleContextHolder.getLocale();
System.out.println("locale " + locale);
String appName = messageSource.getMessage("app.name", null, locale);
String smsContent = messageSource.getMessage("sms.password.recovery", new Object[] { otp }, locale);
Message message = new TextMessage(appName, phone, smsContent);
try {
smsClient.submitMessage(message);
} catch (NexmoClientException | IOException e) {
log.error("Error while sending recovery password message to phone number [{}]", phone, e);
throw new UserActivationException("Error while recovering password for user with phone: " + phone, e);
}
}
这个测试:
@Before
public void setup() {
LocaleContextHolder.resetLocaleContext();
Mockito.when(tokenGenerator.generateOtp(Mockito.any())).thenReturn(14);
}
@Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {
// Mocks.
LocaleContextHolder.setLocale(Locale.ENGLISH, true);
String mockPhone = "333";
User mockUser = mockModelBuilder.user(true, true);
Mockito.when(userDao.findByPhone(mockPhone, User.class)).then(r -> {
// TODO
return Optional.of(mockUser);
});
CountDownLatch latch = new CountDownLatch(1);
ArgumentCaptor<TextMessage> messageCaptor = ArgumentCaptor.forClass(TextMessage.class);
Mockito.when(smsClient.submitMessage(messageCaptor.capture())).then(r -> {
latch.countDown();
throw new NexmoClientException();
});
// Test.
service.sendPasswordRecoverySmsAsync(mockPhone);
latch.await();
// Assertions.
Assert.assertTrue(true);
TextMessage actualMessage = messageCaptor.getValue();
Assert.assertEquals("myApp", actualMessage.getFrom());
Assert.assertEquals(mockPhone, actualMessage.getTo());
Assert.assertEquals("Your password recovery code for myApp app is 14", actualMessage.getMessageBody());
}
我希望我的测试的输出是“en”,如果我只启动这个测试,它就可以正常工作。但是,当我运行所有测试时,输出是“it”。这可能是因为在其他测试中我设置了意大利语区域设置,或者是因为它获得了系统默认值。
但为什么即使我明确地重置它,它也会得到错误的结果呢?
1条答案
按热度按时间f2uvfpb91#
仅出于测试此类本地化案例的目的,您可能只需要在测试方法中添加以下内容。这实际上会将上下文标记为dirty并重新创建它,这取决于您是在测试执行之前还是之后将上下文称为dirty。
请参阅此处的文档
希望这对我有帮助,因为它解决了一个类似的问题。