我有以下非常简单的课程:
public class MyClass
{
private MqttClient field;
public void test() throws MqttException
{
field = new MqttClient(null, null);
field.connect();
}
}
我正在使用
Eclipse Paho's
MqttClient
班级。
我想测试一下
test
方法。为了控制
mqtt客户端
实例我想模拟对象。我的测试课程如下:
public class TestMyClass
{
// Make sure we are running with the PowerMockAgent initialized
static
{
PowerMockAgent.initializeIfNeeded();
}
// Make sure we are using PowerMock
@Rule
public PowerMockRule rule = new PowerMockRule();
// Mocked MqttClient
@Mock
MqttClient field;
// MyClass-Object injected with mocks.
@InjectMocks
MyClass myClass = new MyClass();
@PrepareForTest(MyClass.class)
@Test
public void test() throws Exception
{
// Initialize our mocks from annotations
MockitoAnnotations.initMocks(this);
// Catch the "new MqttClient(null, null);"
PowerMockito.whenNew(MqttClient.class).withAnyArguments().thenReturn(field);
myClass.test();
}
}
当我执行测试时,遇到以下错误:
java.lang.NullPointerException
at test.java.test.MyClass.test(MyClass.java:13)
at test.java.test.TestMyClass.test(TestMyClass.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
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:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
我可以调用任何方法
field
它始终是一个空引用。我的问题是我不知道为什么会这样。
我改变了
领域
其他几个班级,包括
java.awt.point
和
SerializationInstantiatorHelper
(为了测试是否与
mqtt客户端
作为外部依赖项)以及我的项目中的几个类,对这些对象调用适当的方法。在所有这些情况下,问题不存在,测试成功,没有任何问题。模拟对象上的方法是被调用的,它不做任何事情——正如我希望它做的那样。
仅当使用
mqtt客户端
类发生此问题。或者至少我还没有找到其他类来重现这个问题。
老实说,我在这一点上完全迷路了。什么使
mqtt客户端
特别班?为什么我不能像其他班一样嘲笑它?我错过了什么?
//编辑
我通过创建本地版本的
mqtt客户端
,在源代码上复制。老实说,我现在更困惑了。类有三个具有以下签名的构造函数:
1)
public MqttClient( String serverURI,
String clientId) throws MqttException
2)
public MqttClient( String serverURI,
String clientId,
MqttClientPersistence persistence) throws MqttException
3)
public MqttClient( String serverURI,
String clientId,
MqttClientPersistence persistence,
ScheduledExecutorService executorService) throws MqttException
如果这三个构造器中的一个被移除,一切都会工作。
类与这三个构造函数中的两个的任何组合都可以正常工作。
一旦所有三个构造函数都存在,就会出现前面提到的错误消息。
这导致了我的假设,它可能与PowerMockito有关,而不是找不到正确的构造函数?如果是这样的话,那该如何避免呢?