Java 意外的方法调用,但仅使用PartialMock

Java 意外的方法调用,但仅使用PartialMock,java,android,unit-testing,bluetooth,powermock,Java,Android,Unit Testing,Bluetooth,Powermock,当我创建一个常规的mock(即通过调用PowerMock.createMock())时,但当我使用partialMock(通过调用PowerMock.createPartialMock())时,却不能成功地在一个mock对象(使用PowerMock)上建立方法调用期望,我正在绞尽脑汁地试图弄明白这一点以及添加要模拟的方法 下面的代码显示了两个测试(这里我没有断言任何东西,只是演示了失败) 第一个运行时没有错误。 第二个与第一个完全相同,只是我创建了一个部分模拟 第二个测试抛出一个断言错误(文章底

当我创建一个常规的mock(即通过调用
PowerMock.createMock()
)时,但当我使用partialMock(通过调用
PowerMock.createPartialMock()
)时,却不能成功地在一个mock对象(使用PowerMock)上建立方法调用期望,我正在绞尽脑汁地试图弄明白这一点以及添加要模拟的方法

下面的代码显示了两个测试(这里我没有断言任何东西,只是演示了失败)

第一个运行时没有错误。 第二个与第一个完全相同,只是我创建了一个部分模拟

第二个测试抛出一个
断言
错误(文章底部的错误文本),声称对
Bluetooth.getName()
进行了意外的方法调用,好像我没有正确设置期望值一样。但是我使用了与第一次测试相同的期望设置

我对部分模拟有些陌生,所以可能我遗漏了一些东西,但我已经根据PowerMock的文档和我所研究的众多示例设置了代码

请注意,我试图模拟的类是Android类。这是一个
final
类(这就是我使用PowerMock的原因)。我不确定这是否重要(也无法想象为什么这会适用于普通的模拟,而不是部分模拟),但我想我会提到它以防万一

public class PartialMockTests
{
@Test
public void testNormalMock()
{
    BluetoothDevice normalMock = PowerMock.createMock(BluetoothDevice.class);

    // tell EasyMock to expect call to mocked getAddress()
    EasyMock.expect(normalMock.getName()).andReturn("fakeName");
    EasyMock.expectLastCall().anyTimes();
    EasyMock.replay(normalMock);

    //Exercise the mock
    normalMock.getName(); // No error here!

    EasyMock.verify(normalMock);
}

@Test
public void testPartialMock()
{
    BluetoothDevice partialMock =
            PowerMock.createPartialMock(
                    BluetoothDevice.class,
                    "getName", "toString");  //If I don't mock "toString", I get a NPE

    // tell EasyMock to expect call to mocked getAddress()
    EasyMock.expect(partialMock.getName()).andReturn("fakeName");
    EasyMock.expectLastCall().anyTimes();
    EasyMock.replay(partialMock);

    //Exercise the mock
    partialMock.getName(); // Now I get a Assertion Error:  Unexpected Method Call!  Why?

    EasyMock.verify(partialMock);
}
}
以下是断言错误文本:

java.lang.AssertionError:意外的方法调用 BluetoothDevice.getName():位于 org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:44) 在 org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:94) 在 org.easymock.internal.ClassProxyFactory$MockMethodInterceptor.intercept(ClassProxyFactory.java:97) 在 android.bluetooth.BluetoothDevice$$enhancerbyglib$$6c62bd71.getName() 在 my.domain.package.PartialMockTests.testPartialMock(PartialMockTests.java:40) 位于的sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)位于 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)位于 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)位于 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)位于 org.junit.runners.ParentRunner.run(ParentRunner.java:363)位于 org.junit.runner.JUnitCore.run(JUnitCore.java:137)位于 JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 位于的sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) invoke(NativeMethodAccessorImpl.java:62) 在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)