gpt4 book ai didi

java - MockEJB - JUnit Mockito - 无法在第二个单元测试中重新绑定(bind)模拟 EJB

转载 作者:行者123 更新时间:2023-12-01 16:10:08 28 4
gpt4 key购买 nike

您好,我有一个与 MockEJB 相关的问题。我需要编写单元测试来测试调用 EJB 的代码。我使用 Mockito 为 EJB 编写模拟,并使用 MockEJB 来模拟 JNDI 上下文。

我的测试如下所示:

 @Test
public void test1() throws Exception {
// create a mock instance
NetworkManager aMockManager = createMockNetworkManager();
// deploy it in mock container and register it in JNDI
registerMockNetworkManager(aMockManager);

// encapsulates the JNDI lookup
NetworkManager manager = NetworkManagerAccessor.getNetworkManager();
// call a method
manager.deleteObject(new TopicId(-1), null, this.userContext);
// verify that the method was called on the mock
verify(aMockManager).deleteObject(new TopicId(-1), null, this.userContext);
}

@Test
public void test2() throws Exception {
// create a mock instance
NetworkManager aMockManager = createMockNetworkManager();
// deploy it in mock container and register it in JNDI
registerMockNetworkManager(aMockManager);

// encapsulates the JNDI lookup
NetworkManager manager = NetworkManagerAccessor.getNetworkManager();
// call a method
manager.deleteDataItem(new DataItemId(-1), null, null, null);

// verify that the method was called on the mock
verify(aMockManager).deleteDataItem(new DataItemId(-1), null, null, null);
}

第一个测试运行良好,但是第二个测试系统失败(mockito 说未调用预期方法)在调试时,我可以看到第二次尝试将模拟 EJB 部署到 JNDI 时,它是 未部署,并且第一个模拟对象仍然存在。 所以实际上第二个测试是从第一个测试中创建的模拟的 JNDI 中获取的。另请注意,如果我单独运行第二个测试(通过注释第一个测试),它运行良好。

我的设置和清理方法如下所示:

 @Before
public void setupMockJNDI() {
try {

// setup mockEJB
MockContextFactory.setAsInitial();
Context jndiContext = new InitialContext();

// create the mock container
mockContainer = new MockContainer( jndiContext );
} catch (NamingException e) {
e.printStackTrace();
}

}

@After
public void unregisterJNDI() {
// reset mock context
MockContextFactory.revertSetAsInitial();
}

我真的不明白发生了什么,我的测试看起来与模拟 EJB 示例非常相似。有人有想法吗?

谢谢

最佳答案

是的,我找到了答案......就在昨天!事实上它与MockEJB无关,而是与我的代码有关,即进行JNDI查找缓存。此调用:

NetworkManager manager = NetworkManagerAccessor.getNetworkManager();

封装 JNDI 查找,如下所示:

NetworkManagerHome home = (NetworkManagerHome)ServiceLocator.getInstance().getService(NetworkManagerHome.JNDI_NAME, NetworkManagerHome.class);

ServiceLocator 正在静态缓存其 JNDI 查找以及 JNDI 上下文:

public Object getService(String jndiName, Class className) {        
Object narrowedService = null;
if (cache.containsKey(jndiName)) {
narrowedService = cache.get(jndiName);
} else {
// see J2EE design patterns page 197
synchronized(this) {
try {
Object service = ctx.lookup(jndiName);
narrowedService = PortableRemoteObject.narrow(service, className);
} catch (NamingException ne) {
throw new ServiceLocatorException("Cannot find service : "+jndiName, ne);
}
cache.put(jndiName, narrowedService);
}
}
return narrowedService;
}

因此解决方案包括在每次测试之前重置此缓存:

Context jndiContext = new InitialContext();
ServiceLocator.getInstance().reset(jndiContext);

// in ServiceLocator :
public void reset(Context c) {
this.cache = new Hashtable<String, Object>();
this.ctx = c;
}

关于java - MockEJB - JUnit Mockito - 无法在第二个单元测试中重新绑定(bind)模拟 EJB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1565307/

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