gpt4 book ai didi

java - Mockito 何时不替换原始方法行为

转载 作者:行者123 更新时间:2023-12-02 01:59:16 25 4
gpt4 key购买 nike

我有 2 个模块 UserEmail,它们都有 1 个入口点,这是一个外观,其余的是包范围。配置分2个类完成

@Configuration
class UserConfiguration {
@Bean
UserFacade userFacade(UserRepository repository, EmailFacade emailFacade) {
return new UserFacade(repository, emailFacade);
}
}

@Configuration
class EmailConfiguration {
@Bean
EmailFacade emailFacade(EmailSender emailSender) {
return new EmailFacade(emailSender);
}
}

enter image description here

现在,我想编写不需要 Spring 启动的测试。我实现了一个简单的 InMemoryRepository 来实现这一点

@RunWith(MockitoJUnitRunner.class)
public class RegisterUserTest {
@Mock
private EmailFacade emailFacade = new EmailFacade(new FakeEmailSender());

@InjectMocks
private UserFacade userFacade = new UserConfiguration().userFacade(new InMemoryUserRepository(), emailFacade);

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
}

我需要一些假对象来实例化EmailFacade,所以我编写了假实现

public class FakeEmailSender implements EmailSender {
@Override
public void sendEmail(EmailMessage emailMessage) throws RuntimeException {

}
}

在这种情况下,我正在测试 User 域,因此我无论如何都想模拟 Email

我编写了一个测试来检查它是否有效

@Test
public void shouldReturnSendingFailed() {
Mockito.when(emailFacade.sendUserVerificationEmail(Mockito.any())).thenReturn(Either.left(EmailError.SENDING_FAILED));
assertThat(userFacade.registerNewUser(RegisterUserDto.builder()
.username(USERNAME_4)
.email(VALID_EMAIL)
.password(VALID_PASSWORD).build()).getLeft(), is(EmailError.SENDING_FAILED));
}

但事实并非如此......运行此测试后我得到了

java.util.NoSuchElementException: getLeft() on Right

编辑#

regiserNewUser()方法

 Either<DomainError, SuccessMessage> register(RegisterUserDto registerUserDto) {
if(userRepository.findUser(registerUserDto.getUsername()).isPresent())
return Either.left(UserError.USERNAME_ALREADY_EXISTS);
var userCreationResult = User.createUser(registerUserDto);
var savedUser = userCreationResult.map(this::saveUser);
var emailDto = savedUser.map(this::createVerificationEmail);
return emailDto.isRight() ? emailFacade.sendUserVerificationEmail(emailDto.get())
: Either.left(emailDto.getLeft());
}

编辑2#具有以下测试配置

@RunWith(MockitoJUnitRunner.class)
public class RegisterUserTest {
@Mock
private EmailFacade emailFacade;

@InjectMocks
private UserFacade userFacade = new UserConfiguration().userFacade(new InMemoryUserRepository(), emailFacade);

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
}

我在这里得到了空指针,registerNewUser()的最后一行。
enter image description here

最佳答案

尝试运行此代码

@RunWith(MockitoJUnitRunner.class)
public class RegisterUserTest {
@Mock
private EmailFacade emailFacade;

private UserFacade userFacade;

@Before
public void setUp() {
userFacade = new UserConfiguration().userFacade(new InMemoryUserRepository(), emailFacade);
}
}

您的代码存在一些问题:

  1. 您初始化模拟两次。如果您使用Mockito runner,则不需要在setUp方法中调用initMocks
  2. 您正在尝试将模拟注入(inject)已初始化的对象。但是您尝试注入(inject)的字段也会传递给构造函数。请阅读@InjectMocks doc,检查用于注入(inject)模拟的策略:
    • 构造函数(此处未使用,已初始化对象)
    • 二传手(你有吗?)
    • 字段(不是最终的)

每个策略都有详细信息(请参阅上面我的问题)。如果没有匹配的 staregy,Mockito 将默默失败。事实上,您在构造函数中传递一个对象,然后依赖 setter 或字段注入(inject),这使得这段代码不必要地复杂。

关于java - Mockito 何时不替换原始方法行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57383547/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com