意外的方法调用,但仅限于PartialMock

时间:2016-01-31 07:08:43

标签: java android unit-testing bluetooth powermock

当我创建一个常规模拟(即通过调用PowerMock.createMock())时,我试图弄清楚为什么我可以在模拟对象上成功建立方法调用期望(使用PowerMock),但是我撕裂了我的头发,但是不是当我使用partialMock(通过调用PowerMock.createPartialMock())并添加要被模拟的方法时。

下面的代码显示了两个测试(我在这里没有声明任何内容,只是演示了失败)。

第一个运行没有错误。 第二个与第一个完全一样,除了我创建一个局部模拟。

第二次测试引发Assertion错误(帖子底部的错误文本)声称对Bluetooth.getName()发出了意外的方法调用,好像我没有正确设置期望值。但我使用与第一次测试中相同的期望设置!

我对Partial Mocks有点新鲜,所以也许我错过了一些东西,但我根据PowerMock的文档和我所做的众多例子设置了我的代码。审查了。

请注意,我尝试模拟的类是Android BluetoothDevice类。它是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():at   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 $$ EnhancerByCGLIB $$ 6c62bd71.getName()     在   my.domain.package.PartialMockTests.testPartialMock(PartialMockTests.java:40)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在   org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)     在   org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)     在   org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)     在   org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)     在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at   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)at at   org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at at   org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at at   org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)at at   org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)at at   org.junit.runners.ParentRunner.run(ParentRunner.java:363)at at   org.junit.runner.JUnitCore.run(JUnitCore.java:137)at at   com.intellij.junit4.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)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     在   com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

0 个答案:

没有答案