Spring LocaleContextHolder设置不正确 [英] Spring LocaleContextHolder not correctly set

查看:2394
本文介绍了Spring LocaleContextHolder设置不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Spring LocaleContextHolder上遇到了一些问题.

I'm having some issues with 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".这可能是因为在其他测试中我设置了ITALIAN语言环境,还是因为它正在获得系统默认值.

I would expect the ouput of my test being "en" and this works properly if I launch only this one. However, when I run all my tests, the ouput is "it". This is probably either because in other tests I set an ITALIAN locale or because it's getting the system default.

但是,即使我明确地重置了它,为什么它还是得到了错误的信息呢?

But why is it getting the wrong one even when I'm resetting it explicitly?

推荐答案

仅出于测试此类本地化案例的目的,您可能仅需要在测试方法上添加以下内容.这实际上将标记上下文为Dirty并重新创建它,具体取决于您是在执行测试之前还是之后将上下文称为Dirty.

For solely the purpose of testing such localization cases, you might just need to add the following on your test method. This will essentially mark the context Dirty and recreate it, depending on whether you mention as the context being Dirty either before or After the test execution.

@DirtiesContext(methodMode = MethodMode.AFTER_METHOD)
@Test(timeout = 3000)
public void testSendPasswordRecoverySmsAsyncError() throws Exception {...

请参阅文档希望这会有所帮助,因为它为我解决了类似的问题.

Hope this helps, as it resolved a similar problem for me.

这篇关于Spring LocaleContextHolder设置不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆