Mockito spy возвращает результат, отличный от фактического вызова метода

#java #mockito #powermock #vtd-xml

#java #mockito #powermock #vtd-xml

Вопрос:

У меня есть следующий код:

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

Я пишу модульный тест для этого метода. Когда я запускаю метод без издевательства, VTDGen parseFile метод возвращает true . Однако, когда я издеваюсь над ним с помощью spy, он возвращается 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 не должны изменять поведение обернутых объектов, так почему же я получаю false вместо true?

Комментарии:

1. Мне нужна дополнительная помощь от вас, либо в вашем методе MyTest (), либо в вашем методе parse (), либо, возможно, в VTDGen.ParseFile(). Вы создаете spy, но я не вижу кода проверки. Откуда берется myFile? Мне, вероятно, не нужна ВСЯ эта информация, но больше, чем вы указали до сих пор.

2. Извините за поздний ответ. Материал для выходных. myTest вызывает parse и myFile передается. Дело в том, что если я закомментирую PowerMockito.whenNew , vg.parseFile возвращает true , но с whenNew на месте (значит, используется шпион) vg.parseFile возвращает false . Я думал, что шпион должен просто перенести вызов в фактический экземпляр, так почему возвращаемое значение отличается?

3. Итак, вы не занимаетесь каким-либо фактическим «шпионажем» за своим шпионом прямо сейчас? Откуда вы знаете, что vg.parseFile возвращается?

4. Отладчик. Возврат из parse был не тем, что я пытался протестировать, но мешает мне перейти к коду, который я тестирую. Я вытащил все остальное, что могло повлиять на тест, и перешел к шпиону, вызывающему проблему.

5. vtdGenSpy.parseFile(myFile.getAbsolutePath(), false) (без PowerMockito) также возвращает false ?

Ответ №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);
    }
}
  

Комментарии:

1. Я пробовал это с PowerMockito.spy безрезультатно. Как я могу определить, совместимы ли Powermock / Mockito? Я использую Mockito 1.8.5 и Powermock 1.4.9 (у меня нет доступа к PowerMock 1.4.10).

2. Похоже, что начиная с версии PowerMock 1.3.9, он поддерживал Mockito 1.8.5

Ответ №3:

Это было в ответе Ориена, хотя и косвенно: Вы включили @PrepareForTest(ClassCallingNewVTDGen.class )?

Это вызов класса

 new VTDGen()
  

это должно быть подготовлено для тестирования. В ответе Ориена это Uo.class

Источник

Комментарии:

1. Да, я сделал. Я подтвердил, что тестируемый класс получил spy.