Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Mockito - фиктивная базовая реализация при тестировании реализации производного класса того же метода

Автор вопроса: VivekОтветов: 1

Я использую Mockito для модульного тестирования. У меня есть следующие классы:

public class Base {
    public void say() {
        System.out.println("Base"); // some work in the base class
    }
}

public class Derived extends Base {
    @Override
    public void say() {
        super.say();   // do the base class work
        System.out.println("Derived"); // some additional work in the derived class
    }
}

Теперь я хочу протестировать метод say() класса Derived, издеваясь над базовым методом say(). Я последовал предложению здесь: Mockito Как издеваться только над вызовом метода суперкласса и теперь у меня есть.

public class DerivedTest {
    @Test
    public void testSay() {
        Derived obj = Mockito.spy(new Derived());
        Mockito.doNothing().when((Base)obj).say();
        obj.say();
        // assert only "Derived" was output
    }
}

Но это не работает, так как имитирует как базовую, так и производную реализацию класса. Я хочу проверить только дополнительную логику в производном классе.

Как я могу это сделать.

Обновление: мое решение

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

public class Derived extends Base {
    @Override
    public void say() {
        super.say();   // do the base class work
        doAdditionalWork();  // some additional work in the derived class
    }

    void doAdditionalWork() {
        System.out.println("Derived");
    }
}

public class DerivedTest {
    @Test
    public void testDoAdditionalWork() {
        Derived obj = new Derived();
        obj.doAdditionalWork();
        // assert only "Derived" was output
    }
}

Это означает, что я все еще не тестирую производный метод say(), но, учитывая, что логика там довольно проста, я надеюсь, что меня можно за это извинить. Другим недостатком является то, что я не могу иметь более строгую видимость, чем пакет-частный для метода doAdditionalWork().

javaunit-testingmockito

Ответы

Ответ 1 · рейтинг 2 · Mureinik

Когда вы spy создаете объект, вы полностью заменяете реализацию метода (методов), для которого вы определили фиктивное поведение. Итак, как вы отметили в вопросе, это не сработает.

Один из трюков заключается в том, чтобы извлечь метод additionalBehavior() и протестировать только его, без шпионажа или насмешек:

public class Base {
    public void say() {
        System.out.println("Base"); // some work in the base class
        additionalBehavior();
    }

    protected void additionalBehavior() {
        // No implementation. Alternatively - make it abstract
    }
}

public class Derived extends Base {
    @Override
    protected void additionalBehavior() {
        System.out.println("Derived"); // some additional work in the derived class
    }
}

public class DerivedTest {
    @Test
    public void testAdditionalBehavior() {
        Derived obj = new Derived();
        obj.additioanlBehavior();
        // assert that "Derived" was the output
    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы