【问题标题】:Mockito spy returns different result than actual method callMockito 间谍返回的结果与实际方法调用不同
【发布时间】:2011-11-09 13:45:19
【问题描述】:

我有以下代码:

public Object parse(){
      ....
      VTDGen vg = new VTDGen();
      boolean parsed = vg.parseFile(myFile.getAbsolutePath(), false);
}

我正在为此方法编写单元测试。当我在不模拟VTDGen 的情况下运行该方法时,parseFile 方法返回true。但是,当我用间谍模拟它时,它会返回 false。

我的测试如下:

@Before
public void setup(){
     VTDGen vtgGen = new VTDGen();
     VTDGen vtgGenSpy = PowerMockito.spy(vtdGen);
     PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenSpy);

}


@Test
public void myTest(){
    // when I run the test parseFile returns false
    // if I remove the mocking in the setup, parseFile returns true
}

我的印象是 Mockito 的间谍对象不应该改变包装对象的行为,那么为什么我得到的是假而不是真?

【问题讨论】:

  • 我需要您的更多帮助,无论是在您的 myTest() 方法还是在您的 parse() 方法中,或者可能是 VTDGen.parseFile()。您正在创建间谍,但我没有看到验证码。我的文件来自哪里?我可能不需要所有这些信息,但比你目前提供的更多。
  • 抱歉回复晚了。周末的东西。 myTest 调用 parse 和 myFile 被传入。关键是如果我注释掉 PowerMockito.whenNew,vg.parseFile 返回 true 但 whenNew 就位(所以使用了间谍)@ 987654334@ 返回false。我认为间谍应该只是包装对实际实例的调用,那么为什么返回的值不同?
  • 所以你现在没有对你的间谍进行任何实际的“间谍活动”?你怎么知道vg.parseFile返回的是什么?
  • 调试器。 parse 的返回不是我想要测试的,而是阻止我访问我正在测试的代码。我删除了可能影响测试的所有其他内容,并找到了导致问题的间谍。
  • vtdGenSpy.parseFile(myFile.getAbsolutePath(), false)(没有 PowerMockito)是否也返回 false?

标签: java mockito powermock vtd-xml


【解决方案1】:

可能是因为您返回的是vtdGenMock 而不是vtgGenSpy

PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenMock);

【讨论】:

    【解决方案2】:

    在监视 Powermocked 类时,您应该使用 PowerMockito.spy(...) 方法:

    VTDGen vtgGenSpy = PowerMockito.spy(vtdGen);
    

    还要确保您的 Mockito/Powermock 版本组合兼容。我正在使用 Mockito 1.8.5 和 Powermock 1.4.10。

    我通过了以下测试 (TestNG):

    @PrepareForTest({VTDGen.class, Uo.class})
    public class UoTest extends PowerMockTestCase {
    
        private VTDGen vtdGen;
        private VTDGen vtdGenSpy;
        private Uo unitUnderTest;
    
        @BeforeMethod
        public void setup() {
            vtdGen = new VTDGen();
            vtdGenSpy = PowerMockito.spy(vtdGen);
            unitUnderTest = new Uo();
        }
    
        @Test
        public void testWithSpy() throws Exception {
            PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGenSpy);
    
            boolean result = unitUnderTest.parse();
    
            assertTrue(result);
        }
    
        @Test
        public void testWithoutSpy() throws Exception {
            PowerMockito.whenNew(VTDGen.class).withNoArguments().thenReturn(vtdGen);
    
            boolean result = unitUnderTest.parse();
    
            assertTrue(result);
        }
    }
    

    对于被测单元:

    public class Uo {
        public boolean parse() {
            VTDGen vg = new VTDGen();
            return vg.parseFile("test.xml", false);
        }
    }
    

    【讨论】:

    • 我已经用PowerMockito.spy 尝试过,但无济于事。如何判断 Powermock / Mockito 是否兼容?我使用的是 Mockito 1.8.5 和 Powermock 1.4.9(我无权访问 PowerMock 1.4.10)。
    • 从 PowerMock 1.3.9 开始,它支持 Mockito 1.8.5
    【解决方案3】:

    这是在 orien 的回复中,虽然有点间接:你是否包括 @PrepareForTest(ClassCallingNewVTDGen.class)?

    这是类调用

    new VTDGen()
    

    必须为测试做好准备。在东方的回答中,它是 Uo.class

    Source

    【讨论】:

    • 是的,我做到了。我确实确认了被测类收到了间谍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多