【发布时间】:2021-11-09 13:27:33
【问题描述】:
我有课
@Service
@RequiredArgsConstructor
public class UserService {
private final WalletService walletService;
public void increaseBalance() {
walletService.increaseBalance();
}
}
@Service
@RequiredArgsConstructor
public class WalletService {
public void increaseBalance() {}
}
和测试类
@RunWith(SpringRunner.class)
@SpringBootTest()
public class UserServiceTest {
@MockBean
private UserService userService;
@Test
public void testIncreaseBalance_realMethod() {
//here I want to call real UserService method
doCallRealMethod().when(userService).increaseBalance();
userService.increseBalance();
}
@Test
public void testIncreaseBalance_mockedMethod() {
//here I don't want to call real UserService method
userService.increseBalance();
}
}
在这种情况下,WalletService 没有被注入到 UserService 中。如我所见,原因是 UserService 是一个@MockBean。因此,我在测试中有 NullPointerException。
但是,当我创建 UserService @SpyBean 时,WalletService 被注入到 UserService 中。
有什么方法可以在 UserService 中注入 WalletService 并且仍然将其作为@MockBean?
【问题讨论】:
-
您是想测试
UserService本身的行为,还是需要在完整的应用程序运行时进行测试? -
我想通过完整的应用程序运行来测试 UserService 的行为。我的主要目标是灵活地指定我是要调用 bean 的真实方法还是模拟此方法(如您在两个测试方法中所见)
-
我强烈建议不要在单个测试中混合使用。使用
@SpringBootTest的测试通常是使用实际bean 的集成测试。如果您想对UserService的行为进行单元测试,则只需手动创建WalletService的模拟并将其传递给您也手动创建的UserService实例。 -
我同意你的看法。但是想象一下,如果我在多个测试之间共享相同的 UserService 对象。我这样做是为了保持相同的 ApplicationContext(因为我有很多测试并且不想在每个测试中重新加载上下文)。在某些测试中,我希望 UserService 充当模拟对象,而在其他测试中 - 充当普通的真实对象。有没有办法在不重新加载 ApplicationContext 的情况下做到这一点?
-
如果你在模拟
UserService类,你怎么能测试它?
标签: java spring spring-boot mocking spring-test