Используя Mockito для тестирования абстрактных классов

import os
import shutil

# Gather directory contents
contents = [os.path.join(target_dir, i) for i in os.listdir(target_dir)]

# Iterate and remove each item in the appropriate manner
[os.remove(i) if os.path.isfile(i) or os.path.islink(i) else shutil.rmtree(i) for i in contents]

В предыдущем комментарии также упоминается использование os.scandir в Python 3.5+. Например:

import os
import shutil

with os.scandir(target_dir) as entries:
    for entry in entries:
        if entry.is_file() or entry.is_symlink():
            os.remove(entry.path)
        elif entry.is_dir():
            shutil.rmtree(entry.path)
202
задан Community 23 May 2017 в 02:10
поделиться

4 ответа

Предполагая, что ваши тестовые классы находятся в том же пакете (под другим исходным корнем), что и тестируемые классы, вы можете просто создать макет:

YourClass yourObject = mock(YourClass.class);

и вызвать методы, которые вы хотите протестировать, просто как и любой другой метод.

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

Все, что это делает - создает конкретный экземпляр YouClass и избавляет вас от необходимости предоставлять пустые реализации каждого абстрактного метода.

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

2
ответ дан 23 November 2019 в 05:00
поделиться

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

При тестировании абстрактного класса вы хотите, чтобы выполнять неабстрактные методы объекта тестирования (SUT), поэтому фреймворк имитирования - это не то, что вам нужно.

Отчасти путаница заключается в том, что ответ на вопрос, с которым вы связались, сказал, что нужно вручную создать макет это происходит от вашего абстрактного класса. Я бы не назвал такой урок издевательством. Мок - это класс, который используется как замена зависимости, запрограммирован с ожиданиями, и его можно запросить, чтобы увидеть, оправдываются ли эти ожидания.

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

Альтернативным решением было бы сделать сам тестовый пример абстрактным с помощью абстрактного метода для создания SUT (другими словами , в тестовом примере будет использоваться шаблон проектирования Template Method ).

14
ответ дан 23 November 2019 в 05:00
поделиться

Попробуйте использовать собственный ответ.

Например:

import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

public class CustomAnswer implements Answer<Object> {

    public Object answer(InvocationOnMock invocation) throws Throwable {

        Answer<Object> answer = null;

        if (isAbstract(invocation.getMethod().getModifiers())) {

            answer = Mockito.RETURNS_DEFAULTS;

        } else {

            answer = Mockito.CALLS_REAL_METHODS;
        }

        return answer.answer(invocation);
    }
}

Он вернет макет для абстрактных методов и вызовет реальный метод для конкретных методов.

8
ответ дан 23 November 2019 в 05:00
поделиться

Вы можете добиться этого с помощью шпиона (хотя используйте последнюю версию Mockito 1.8+).

public abstract class MyAbstract {
  public String concrete() {
    return abstractMethod();
  }
  public abstract String abstractMethod();
}

public class MyAbstractImpl extends MyAbstract {
  public String abstractMethod() {
    return null;
  }
}

// your test code below

MyAbstractImpl abstractImpl = spy(new MyAbstractImpl());
doReturn("Blah").when(abstractImpl).abstractMethod();
assertTrue("Blah".equals(abstractImpl.concrete()));
16
ответ дан 23 November 2019 в 05:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: