java - Mockito 不识别类
问题描述
我试图通过模拟一个类来使用weld-junit5。我嘲笑这门课,因为我想知道它多久会被调用一次。
但是每次我尝试 Mockito.verify() 这个模拟类时,它都会抛出一个“NotAMockException”
Intellij 调试器正在验证该字段:"Mock for MessageService, hashCode: XY"
我已经尝试将我的测试类添加到 WeldInitiator 中,但它不想工作。
“MessageService”是一个真正的类,而不是一个接口(接口也不起作用)
@EnableWeld
class GameServiceTest {
@WeldSetup
public WeldInitiator weld = WeldInitiator.from(GameService.class, GameCache.class,
/** Some More **/,
GameServiceTest.class).build();
@Produces
@ApplicationScoped
public MessageService createMessageServiceMock() {
return mock(MessageService.class);
}
@Inject
private MessageService messageService;
@Inject
private GameService gameService;
@Test
void handleRunningGames() {
this.gameService.handleRunningGames(null, mock(Session.class));
// This will throw a org.mockito.exceptions.misusing.NotAMockException
Mockito.verify(messageService, Mockito.times(1)).writeMessage(any(), any());
}
}
我希望 Injected MessageService 是一个真正的模拟,我可以在其上调用每个 Mockito 函数,但似乎并非如此。
我有什么问题吗,或者这样做的正确方法是什么?
我想我刚刚解决了这个问题:
private static final MessageService messageService = mock(MessageService.class);
@Produces
@ApplicationScoped
public MessageService createMessageServiceMock() {
return messageService;
}
解决方案
提供一些背景知识,它的工作方式是 Weld 让 Mockito 创建所需的对象,然后将其作为上下文 bean 实例。
但是,在 CDI 中,任何具有正常范围的 bean 都需要有一个传递的代理而不是该实例。因此,您的生产者实际上所做的(因为它是@ApplicationScoped
)是创建对象,将其存储在上下文中,然后还创建一个代理并传递该代理。代理是一个不同的对象(没有状态的委托),它“知道”如何获取对实际实例的引用。
所以发生的事情是代理被注入到该字段中,并且您正在通过Mockito.verify()
调用检查代理对象。显然,代理不是模拟本身,因此它失败了。正如用户@second 所建议的,Weld 提供了一个 API 来解包代理并获取上下文实例。我认为 API 并不“丑陋”,它只是用户不应该最关心的事情,但有时你无法避免它。
您可以通过使用一些伪作用域来避免使用代理,这些伪作用域是@Dependent
或 CDI @Singleton
。有了它,它应该也能正常工作,只要它用于测试,用单例替换应用程序范围就可以了。
至于你的解决方法,我看不出它是如何解决任何问题的——它基本上是同一个生产者,并且由于范围的原因,它只会被调用一次,因此静态字段不会有任何区别(因为会有一个单一的模拟调用创建)。你有没有改变其他的东西?
推荐阅读
- python - Python实现中的双向BFS
- c++ - 为什么我会遇到分段错误?
- c++ - SFML 游戏中的向量下标超出范围
- python - 如何让子字符串以多个字符结尾并且至少有 n 个字符
- android - 我尝试在本机反应中移动一页另一页,但 routes.js 出现问题
- c# - 如何定义模式表级别
- scala - SLICK:使用一个 slick api 调用在 3 个不同的表中插入值
- python-3.x - 使用 python 3 和 tkinter 在树视图字段中添加多个图标
- python - 无法在 Python 中显示 TreeView
- mongodb - 如何处理typeORM中的mongodb聚合字段