Юнит-тестирование с mockito (частичное издевательство) - PullRequest
3 голосов
/ 22 ноября 2010

У меня проблема с Мокито.

Можно ли сделать такую ​​вещь:

ClassX x = mock(ClassX.class)
when(x.methodB()).thenReturn("toto");
String result = x.methodA();

Я работаю с Mockito 1.7.

Я видел, что была "шпионская" система, но они говорят, что не рекомендуется использовать ее (почему?) На предмете, который мы тестируем ...

Я все равно попробовал эту шпионскую функцию, но у меня странное поведение.

Проверьте, что я хочу сделать:

Реальный код:

String methodA(String arg) {
    return this.methodB(arg);
}

String methodB(String arg) {
    return "toto";
}

Тестовый код:

@Test
public void testTest() {
    final ClassX x = spy( new ClassX() );
    final String argument = "arg";
    doReturn("good").when(helper).methodB(argument);
    assertTrue(  x.methodB(argument).equals("good") );
    assertTrue(  x.methodA(argument).equals("good") );
}  

Как они сказали, я избежал синтаксиса when thenReturn, который может быть проблемой со шпионом (но он все равно не работает)

Странно то, что: assertTrue (x.methodB (аргумент) .equals («хорошо»)); все в порядке

только второй assertTrue (x.methodA (аргумент) .equals («хорошо»)); не в порядке

На самом деле helper.methodA (аргумент) возвращает «toto» -> реальный результат, а не фиктивный результат

Невозможно сказать, чтобы mockito вернул "good" в этом случае ??? Кажется, когда тестовый класс вызывает methodB, это нормально, но если метод шпиона вызывает методB, он больше не работает ...

Я не знаю, что делать ... странно ли проводить модульное тестирование 2 методов одного класса и делать тесты независимыми друг от друга, чтобы известная среда фиктивного тестирования не реализовала это основная функция? Разве это не то, что мы называем настоящим юнит-тестированием? Не понимаю, почему говорят, чтобы не использовать шпионский метод на тестируемом объекте ...

Спасибо

Ответы [ 2 ]

4 голосов
/ 03 января 2011

ОБНОВЛЕНИЕ: я написал материал ниже, а через несколько мгновений обнаружил .thenCallRealMethod (), который позволяет эффективно выполнять частичную заглушку.Авторы Mockito рекомендуют использовать рефакторинг для разделения зависимостей на разные классы;но они дают возможность частично заглушить.Я добавил тестовый метод, чтобы продемонстрировать этот подход, и оставляю свои оригинальные комментарии.

ОРИГИНАЛ: Мне действительно нравится Mockito, но это единственное место, где EasyMock побеждает.У меня есть два решения для вас, которые не связаны с Mockito.Первый - переопределить methodB в вашем тестовом экземпляре.Другой - частично издеваться над EasyMock:

import org.junit.Test;
import static org.junit.Assert.*;
import static org.easymock.EasyMock.*;

public class PartialMockTest {

    class ClassX {
        String methodA(String arg) {return methodB(arg);}
        String methodB(String arg) {return "toto";}
    }

    @Test
    public void MockitoOnClassX(){
        ClassX classx = mock(ClassX.class);
        when(classx.methodB("hiyas")).thenReturn("tomtom");
        when(classx.methodA(anyString())).thenCallRealMethod();
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }


    @Test
    public void OverrideOnClassX() {
        ClassX classx = new ClassX(){@Override String methodB(String arg){return "tomtom";}};
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }

    @Test
    public void PartialMockOnClassX() throws NoSuchMethodException {
        ClassX classx = createMockBuilder(ClassX.class).addMockedMethod("methodB").createMock();
        expect(classx.methodA("hiyas")).andReturn("tomtom");
        replay(classx);
        String response = classx.methodA("hiyas");
        assertEquals("tomtom",response);
    }

}
2 голосов
/ 22 ноября 2010

Шпион - это объект, отличный от шпионского объекта. Шпион только делегирует шпионскому объекту. Поэтому, когда шпионский объект вызывает метод B из метода A, он вызывает его сам, а не шпион.

...