如何使用 EasyMock 从模拟接口调用方法
How to call a method from a mocked interface using EasyMock
我正在为 class 编写 Junit 单元测试,我在以下行中得到 java.lang.NullPointerException:
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
我认为(虽然我不确定)它与我从模拟接口中调用的方法 (getDeviceControlHandler) 有关。因为我在提到的行之前添加了这行代码:
Assert.assertNotNull(comLineConfigurationHandlerMock.getDeviceControlHandler());
我遇到以下错误:
java.lang.AssertionError
我被困在这里,真的需要一些帮助。
提前致谢。
抛出的异常:
java.lang.NullPointerException
at de.myproject.project.classTest.testGetParameters(classTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
这是笔试:
public class classTest {
// class under test
private classUnderTest classUnderTest;
private LineConfigurationHandler LineConfigurationHandlerMock;
private IMocksControl mocksControl;
List<DeviceParameter> myDeviceParameters;
DeviceParameter deviceParameter1;
DeviceParameter deviceParameter2;
@Before
public void setUp() throws Exception
{
mocksControl = EasyMock.createControl();
LineConfigurationHandlerMock = mocksControl.createMock(LineConfigurationHandler.class);
classUnderTest = new classUnderTest();
classUnderTest.setLineConfigurationHandler(LineConfigurationHandlerMock);
String item1 = "item1";
myDeviceParameters = new ArrayList<DeviceParameter>();
myDeviceParameters.add(deviceParameter1);
myDeviceParameters.add(deviceParameter2);
//Other stuff
}
@Test
public void testGetParameters()
{
expect(LineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
mocksControl.replay();
//Some code .....
}
}
这是正在测试的 class :
public Class ClassUnderTest
{
@Inject
private LineConfigurationHandler lineConfigurationHandler;
public List<DeviceParameter> getDeviceParameters(String deviceId)
{
// Method implementation
}
@Required
public void setLineConfigurationHandler(LineConfigurationHandler lineConfigurationHandler)
{
this.lineConfigurationHandler = lineConfigurationHandler;
}
}
声明方法的接口
public interface LineConfigurationHandler {
DeviceControlHandler getDeviceControlHandler();
//other Method declaration ...
}
DeviceControlHandler.class
public interface DeviceControlHandler extends Serializable{
List<DeviceParameter> getDeviceParameters(String deviceId);
//Other methods declaration ...
}
这并不简单,但非常确定:
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
该行包含 两个 项可以抛出 NPE:
A) lineConfigurationHandlerMock --> 该对象可以为 NULL
B) .getDeviceControlHandler() --> 该方法可以 return NULL
就是这样。你可以做简单的打印输出,比如
System.out.println("mock: " + lineConfigurationHandlerMock)
System.out.println("handler: " + lineConfigurationHandlerMock.getDeviceControlHandler())
找出哪个为空。在您的情况下,我认为您缺少 lineConfigurationHandlerMock 对象的设置:当调用 getDeviceControlHandler() 时,您必须告诉它 return 什么。
为此,您首先必须创建 另一个 模拟对象,在调用 getDeviceControlHandler() 时应 returned。而另一个模拟,你必须配置调用 getDeviceParameters()!
换句话说:您不能像 "mock.getA().doSomething()" 那样指定 - 相反,您需要另一个 "mockedA",您告诉 "doSomething()";然后你告诉 "mock" getA() 应该 return "mockedA".
更新:我不熟悉这些注释;我习惯用"EasyMock in a bare metal mode";喜欢
SomeObject innerMock = EasyMock.createMock(SomeObject);
expect(innerMock.doSomething()).andReturn("who cares");
SomeOther outerMock = EasyMock.createMock(SomeOther);
expect(outerMock.getDeviceControlHandler("sounds familiar")).andReturn(innerMock);
我正在为 class 编写 Junit 单元测试,我在以下行中得到 java.lang.NullPointerException:
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
我认为(虽然我不确定)它与我从模拟接口中调用的方法 (getDeviceControlHandler) 有关。因为我在提到的行之前添加了这行代码:
Assert.assertNotNull(comLineConfigurationHandlerMock.getDeviceControlHandler());
我遇到以下错误:
java.lang.AssertionError
我被困在这里,真的需要一些帮助。
提前致谢。
抛出的异常:
java.lang.NullPointerException
at de.myproject.project.classTest.testGetParameters(classTest.java:123)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
这是笔试:
public class classTest {
// class under test
private classUnderTest classUnderTest;
private LineConfigurationHandler LineConfigurationHandlerMock;
private IMocksControl mocksControl;
List<DeviceParameter> myDeviceParameters;
DeviceParameter deviceParameter1;
DeviceParameter deviceParameter2;
@Before
public void setUp() throws Exception
{
mocksControl = EasyMock.createControl();
LineConfigurationHandlerMock = mocksControl.createMock(LineConfigurationHandler.class);
classUnderTest = new classUnderTest();
classUnderTest.setLineConfigurationHandler(LineConfigurationHandlerMock);
String item1 = "item1";
myDeviceParameters = new ArrayList<DeviceParameter>();
myDeviceParameters.add(deviceParameter1);
myDeviceParameters.add(deviceParameter2);
//Other stuff
}
@Test
public void testGetParameters()
{
expect(LineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
mocksControl.replay();
//Some code .....
}
}
这是正在测试的 class :
public Class ClassUnderTest
{
@Inject
private LineConfigurationHandler lineConfigurationHandler;
public List<DeviceParameter> getDeviceParameters(String deviceId)
{
// Method implementation
}
@Required
public void setLineConfigurationHandler(LineConfigurationHandler lineConfigurationHandler)
{
this.lineConfigurationHandler = lineConfigurationHandler;
}
}
声明方法的接口
public interface LineConfigurationHandler {
DeviceControlHandler getDeviceControlHandler();
//other Method declaration ...
}
DeviceControlHandler.class
public interface DeviceControlHandler extends Serializable{
List<DeviceParameter> getDeviceParameters(String deviceId);
//Other methods declaration ...
}
这并不简单,但非常确定:
expect(lineConfigurationHandlerMock.getDeviceControlHandler().getDeviceParameters(item1)).andReturn(myDeviceParameters);
该行包含 两个 项可以抛出 NPE:
A) lineConfigurationHandlerMock --> 该对象可以为 NULL
B) .getDeviceControlHandler() --> 该方法可以 return NULL
就是这样。你可以做简单的打印输出,比如
System.out.println("mock: " + lineConfigurationHandlerMock)
System.out.println("handler: " + lineConfigurationHandlerMock.getDeviceControlHandler())
找出哪个为空。在您的情况下,我认为您缺少 lineConfigurationHandlerMock 对象的设置:当调用 getDeviceControlHandler() 时,您必须告诉它 return 什么。
为此,您首先必须创建 另一个 模拟对象,在调用 getDeviceControlHandler() 时应 returned。而另一个模拟,你必须配置调用 getDeviceParameters()!
换句话说:您不能像 "mock.getA().doSomething()" 那样指定 - 相反,您需要另一个 "mockedA",您告诉 "doSomething()";然后你告诉 "mock" getA() 应该 return "mockedA".
更新:我不熟悉这些注释;我习惯用"EasyMock in a bare metal mode";喜欢
SomeObject innerMock = EasyMock.createMock(SomeObject);
expect(innerMock.doSomething()).andReturn("who cares");
SomeOther outerMock = EasyMock.createMock(SomeOther);
expect(outerMock.getDeviceControlHandler("sounds familiar")).andReturn(innerMock);