Jmockit TestNG/JUnit NullPointerException 与 Seam
这些天我一直在使用jmock和seam,但它不足以模拟final/static/enums。所以我尝试使用 JMockit。然而每次我跑步时,我都会得到NPE。甚至无法调试,下面是示例代码
public class TestJmockit extends SeamTest {
@Mocked Dependency dependencyInCodeToTest;
CodeToTest bean = new CodeToTest();
@Test
public void testSaveSectionChangesJMockit() throws Exception {
new AbstractSeamTest.ComponentTest() {
@Override
protected void testComponents() throws Exception {
new NonStrictExpectations()
{
{
dependencyInCodeToTest.getLabel(); result = "Normal";
}
};
bean.execute();
}
}.run();
}
}
实际代码..
package com.abc.action.account.information;
import com.abc.vo.account.ExternalAccountStatus;
import com.abc.vo.account.information.ExternalAccountStatusClosedInfo;
import com.abc.vo.account.information.ExternalAccountStatusInfo;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.jboss.seam.mock.AbstractSeamTest;
import org.jboss.seam.mock.SeamTest;
import org.junit.Test;
public class ConsumerAccountInformationActionTestJmockit extends SeamTest {
@Mocked ExternalAccountStatus mockExternalAccountStatus;
@Mocked ExternalAccountStatusInfo mockExternalAccountStatusInfo;
// ConsumerAccountInformationAction bean = new ConsumerAccountInformationAction();
@Test
public void testSaveSectionChangesJMockit() throws Exception {
new AbstractSeamTest.ComponentTest() {
@Override
protected void testComponents() throws Exception {
new NonStrictExpectations()
{
{
mockExternalAccountStatus.getLabel(); result = "Normal";
mockExternalAccountStatusInfo.getClosedInfo(); result = new ExternalAccountStatusClosedInfo();
}
};
// bean.saveSectionChanges();
}
}.run();
}
}
如果我在类声明(公共类消费者..)处放置断点,则跳到下一行会导致 NPE。如果我删除代码中的注释行,它会在第一个未注释的行处失败。
我正在使用 Java 1.6 和 IntelliJ IDE。不知道是否与IDE配置有关。
使用 TestNG 我什至没有得到堆栈跟踪,使用 JUnit 我看到下面的内容。
java.lang.NullPointerException
at org.jboss.seam.servlet.ServletApplicationMap.get(ServletApplicationMap.java:54)
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:49)
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:44)
at org.jboss.seam.core.Init.instance(Init.java:117)
at org.jboss.seam.contexts.BusinessProcessContext.<init>(BusinessProcessContext.java:47)
at org.jboss.seam.contexts.TestLifecycle.beginTest(TestLifecycle.java:35)
at org.jboss.seam.mock.AbstractSeamTest$ComponentTest.run(AbstractSeamTest.java:159)
at com.billmelater.csa.action.account.information.ConsumerAccountInformationActionTestJmockit.testSaveSectionChangesJMockit(ConsumerAccountInformationActionTestJmockit.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 255
I had been using jmock with seam all these days, but its not sufficient to mock final/static/enums. So I tried working with JMockit. However everytime I run, I get NPE. Can't even debug, below is sample code
public class TestJmockit extends SeamTest {
@Mocked Dependency dependencyInCodeToTest;
CodeToTest bean = new CodeToTest();
@Test
public void testSaveSectionChangesJMockit() throws Exception {
new AbstractSeamTest.ComponentTest() {
@Override
protected void testComponents() throws Exception {
new NonStrictExpectations()
{
{
dependencyInCodeToTest.getLabel(); result = "Normal";
}
};
bean.execute();
}
}.run();
}
}
Actual Code..
package com.abc.action.account.information;
import com.abc.vo.account.ExternalAccountStatus;
import com.abc.vo.account.information.ExternalAccountStatusClosedInfo;
import com.abc.vo.account.information.ExternalAccountStatusInfo;
import mockit.Mocked;
import mockit.NonStrictExpectations;
import org.jboss.seam.mock.AbstractSeamTest;
import org.jboss.seam.mock.SeamTest;
import org.junit.Test;
public class ConsumerAccountInformationActionTestJmockit extends SeamTest {
@Mocked ExternalAccountStatus mockExternalAccountStatus;
@Mocked ExternalAccountStatusInfo mockExternalAccountStatusInfo;
// ConsumerAccountInformationAction bean = new ConsumerAccountInformationAction();
@Test
public void testSaveSectionChangesJMockit() throws Exception {
new AbstractSeamTest.ComponentTest() {
@Override
protected void testComponents() throws Exception {
new NonStrictExpectations()
{
{
mockExternalAccountStatus.getLabel(); result = "Normal";
mockExternalAccountStatusInfo.getClosedInfo(); result = new ExternalAccountStatusClosedInfo();
}
};
// bean.saveSectionChanges();
}
}.run();
}
}
If I put a breakpoint at class declaratiom (Public Class Consumer..), stepping over to next line causes NPE. If I take out the commented lines in the code, it fails at the first uncommented line.
I am using Java 1.6 and IntelliJ IDE. Wonder if it has to do with IDE configuration.
With TestNG I dont even get the stack trace, with JUnit I see the below..
java.lang.NullPointerException
at org.jboss.seam.servlet.ServletApplicationMap.get(ServletApplicationMap.java:54)
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:49)
at org.jboss.seam.contexts.BasicContext.get(BasicContext.java:44)
at org.jboss.seam.core.Init.instance(Init.java:117)
at org.jboss.seam.contexts.BusinessProcessContext.<init>(BusinessProcessContext.java:47)
at org.jboss.seam.contexts.TestLifecycle.beginTest(TestLifecycle.java:35)
at org.jboss.seam.mock.AbstractSeamTest$ComponentTest.run(AbstractSeamTest.java:159)
at com.billmelater.csa.action.account.information.ConsumerAccountInformationActionTestJmockit.testSaveSectionChangesJMockit(ConsumerAccountInformationActionTestJmockit.java:27)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:73)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:199)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:62)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 255
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

一般反对意见:模拟是为了将你与外部代码隔离开来,
特别是来自您的服务器 wedor 的那些(例如 AbstractSeamtest ) - 所以
您不必初始化它们或让服务器运行等等。
将模拟测试视为保存的调试会话。在你的情况下,你想确保(我猜)该方法
与Seam基础设施或其他协作者正确交互。这可以通过以下方法轻松实现:
General Objection: mocking is there to isolate you from external code,
especially from those coming from your server wendor ( like AbstractSeamtest ) - so
you do not have to initialize them or have server runing or whatever.
Treat mocked test as saved debug session. In your case you like to assure (I'm guessing), that method
interacts correctly with seam infrastructure, or other collaborators. This is easily achieved by something like: