有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Mockito spy返回与实际方法调用不同的结果

我有以下代码:

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的间谍对象不应该改变包装对象的行为,那么为什么我会变假而不是真


共 (3) 个答案

  1. # 1 楼答案

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

    这是全班的电话

    new VTDGen()
    

    必须为测试做好准备。在奥林的回答中,这是Uo。阶级

    Source

  2. # 2 楼答案

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

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

  3. # 3 楼答案

    监视PowerMock类时,应使用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);
        }
    }