При модульном тестировании (с Mockito), я должен "реализовать" внутренний лог c при издевательстве? - PullRequest
1 голос
/ 12 апреля 2020

Редактировать: Извините, мой пример не очень правильный, я его немного изменил.

Я не уверен, правильно ли отображает мой вопрос заголовок.
Например, у меня есть функции:

class Dependency {
    // create an element with id and data, add it into a list and return the element
    public Element addElement(int id, data d) throws SomeException;

    // remove an element from the list and return it
    public Element removeElement(int id) throws SomeException;
}

Тогда я могу высмеять это как:

private Element mockElement(int id, data dt) {
    Element e = mock(Element.class);
    when(e.getId()).thenReturn(id);
    when(e.getData()).thenReturn(dt);
    return e;
}

private Dependency mockDependency() {
    List l = new List();
    Dependency dependency = mock(Dependency.class);    

    // should I "implement" the internal logic when mocking?
    when(dependency.addElement(intCaptor.capture(), dataCapture.capture())).thenAnswer(a->{
        int id = intCaptor.getValue();
        data dt = dataCaptor.getValue();
        if (id < 0) { throw someException; }
        Element e = mockElement(id, dt);
        l.add(e);
        return e;
    };

    when(dependency.removeElement(intCaptor.capture())).thenAnswer(a->{
        int id = intCaptor.getValue();
        if (id < 0) { throw someException; }
        Element e = l.findElementInListById(id);
        if (e == null) { return null; }
        l.remove(e);
        return e;
    };
    return dependency;
}

...

@Test
public void test() {
    ...
    Dependency dependencyMock = mockDependency();
    MyClass c = new MyClass(dependencyMock);

    // it calls dependency.addElement()
    c.addElement(1, data)

    // it calls dependency.removeElement()
    assertEquals(1, c.removeElement(1).getId());
    ...
}    

Это работает, но мне интересно, если это хорошая идея, чтобы сделать это. Все примеры, которые я могу найти в Интернете о Mockito, в основном просты, когда (). Then () заявления. Может кто-нибудь дать мне совет?

1 Ответ

0 голосов
/ 12 апреля 2020

Идея насмешки состоит в том, чтобы проверить функциональность, которую вы написали, насмешки следует указывать только для сервисов, которые используются тестируемым методом.

Например, когда вы тестируете метод public Element addElement(int id, data d) throws SomeException; вы должны вызвать исходную реализацию, а затем вы должны утвердить ответ, который вы ожидаете получить для данного ввода.

Предположим, что внутри addElement метода вы внутренне вызываете службу myService.processData, тогда вы должны смоделировать вызов только на myService.processData, а остальная часть потока должна быть такой, как если бы метод был в реальном сценарии.

Вы должны прочитать больше о модульных тестах, одна ссылка, которую я нашел, здесь

РЕДАКТИРОВАТЬ

В приведенном вами примере Я думаю, что вы сделали следующее: вы поместили код в исходный метод dependency.addElement внутри создаваемого имитируемого объекта. Если вы сделаете это, вам придется менять свой тестовый пример каждый раз, когда вы вносите изменения в код. потому что, как только вы сделаете изменение кода в исходном методе dependency.addElement, код в тестовом классе не будет соответствовать ему c, и вы больше не будете тестировать эту функцию. Даже с этим кодом вы на самом деле не тестируете оригинальную функцию, так как dependency.addElement подделан.

Правильный подход - вызвать оригинальный метод dependency.addElement с известным входным сигналом и подтвердить ответ.

Надеюсь, это объясняет это.

...