gpt4 book ai didi

java - 如何使用 @Transactional 方法将 jmockit 的模拟对象注入(inject)到 spring 管理的对象中?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:05:23 25 4
gpt4 key购买 nike

我正在一个spring项目中写一个TestNG测试用例,使用jmockit模拟依赖。我遇到了一个问题,就是我不能使用 Deencapsulation.setField 来设置对包含 @Transactional 方法的 spring 管理对象的依赖,错误是:

No instance field of name "dataLogManager" found in class java.lang.reflect.Proxy

这里列出了我的示例代码,

测试用例:

public class QueueManagerTest extends AbstractTestNGSpringContextTests {
@Autowired
private QueueManager queueManager;

@Autowired
private ApplicationContext context;

@Autowired
private TransInfoManager transInfoManager;

@Autowired
private Generator generator;

@Autowired
private MessageDTOFactoryBean messageDTOFactoryBean;

@Test(description="單元測試:寫入一筆Data資料,非邊界情況下(無待處理筆數)")
public void writeControlMessage(
@Mocked final TransInfoManager transInfoManager,
@Mocked final DataManager dataManager,
@Mocked final DataLogManager dataLogManager
) {
....
Deencapsulation.setField(queueManager, "dataLogManager", dataLogManager);
Deencapsulation.setField(queueManager, "dataManager", dataManager);
Deencapsulation.setField(queueManager, "transInfoManager", transInfoManager);
....
}
}

服务:

@Service
public interface QueueManager {

@Transactional
MessageDTO putDataIntoQueue(MessageDTO message);

}

有人知道怎么解决这个问题吗?谢谢。

最佳答案

如果您要测试的是某个实现QueueManager 接口(interface)的特定类,那么解决方案就是直接在测试中实例化该类,而不是为此使用 Spring。

异常的原因是Spring实际上为queueManager字段创建了一个proxy类实例,意在装饰真正的实现(代理对象委托(delegate)每一个方法调用到另一个对象,该对象将是实际实现 QueueManager 接口(interface)的应用程序类的实例)。代理类不包含名为“dataLogManager”的字段,所以这就是 Deencapsulation.setField(...) 无法找到它的原因。

如果我提到的第一个解决方案不适用,您仍然可以让 Spring 进行实例化,前提是它还将字段注入(inject)到 queueManager 对象中。要模拟实现 DataLogManager(和其他接口(interface))的类,请使用 @Capturing 代替(或除此之外)@Mocked;这将指示 JMockit 将模拟扩展到所有实现类。

关于java - 如何使用 @Transactional 方法将 jmockit 的模拟对象注入(inject)到 spring 管理的对象中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22497907/

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