Объявление фиктивных параметров Jmockit в @BeforeMethod TestNG

Я некоторое время тестировал поведение своего кода, используя TestNG и JMockit, и у меня не было особых проблем с их комбинацией. Сегодня я столкнулся с ситуацией, когда мне нужно было имитировать одну из моих внутренних зависимостей в так называемой широкой манере, и мне не нужно было держать этот макет, так как ни один из тестовых случаев не касался это напрямую, в то время как они рассчитывали на функциональность издевательской версии. Поэтому, естественно, я поместил издевательскую логику в свой файл @BeforeMethod. Вот пример:

public class SampleTest
{
    @Mocked
    @Cascading
    private InnerDependency dependency;

    @BeforeMethod
    public void beforeMethod()
    {
        new NonStrictExpectations()
        {
            {
                dependency.getOutputStream((String)any);
                result = new Delegate<OutputStream>()
                {
                    public OutputStream getOutputStream(String url)
                    {
                        return null;
                    }
                };
            }
        };
    }

    @Test
    public void testNormalOperation()
    {
        // The test whose desired behavior depends on dependency being mocked out
        // ..
    }
}

Но, поскольку мои тесты не заботятся о фиктивном dependency явно, я не хочу объявлять его как поле тестового класса, в отличие от того, что сделано выше. Насколько я знаю JMockit, остались бы только следующие варианты:

  1. Объявите dependency как локальное фиктивное поле:

    new NonStrictExpectations()
    {
        @Cascading
        private InnerDependency dependency;
        {
            //...
        }
    }
    
  2. Объявите dependency в качестве входного аргумента для beforeMethod(), подобно тому, как это делается для обычных методов @Test:

    @BeforeMethod
    public void beforeMethod(@Mocked @Cascading final InnerDependency dependency)
    {
       // ...
    }
    

Я вижу, что JMockit 1.6+ не нравится первый вариант и выдается предупреждение с WARNING: Local mock field "dependency" should be moved to the test class or converted to a parameter of the test method. Поэтому, чтобы все были довольны, я исключаю этот вариант.

Но для второго варианта TestNG (в настоящее время 6.8.6) выдает исключение при запуске теста, говорящего java.lang.IllegalArgumentException: wrong number of arguments. Я не вижу такого поведения с обычными @Test случаями, переданными с @Mocked параметрами. Даже игра с @Parameter и @Optional не поможет (и не должна!).

Итак, есть ли способ заставить это работать, не объявляя ненужное фиктивное поле тестового класса, или я что-то здесь упускаю?

Спасибо


person Hamid Nazari    schedule 31.01.2014    source источник


Ответы (2)


Только тестовые методы (с аннотацией @Test в JUnit или TestNG) поддерживают фиктивные параметры, поэтому единственный выбор здесь — объявить фиктивное поле на уровне тестового класса.

Даже если он не используется ни в одном методе тестирования, я думаю, что это лучше, чем его объявление в методе установки (с использованием @Before, @BeforeMethod и т. д.). Если бы это было возможно, макет все равно должен был бы применяться ко всем тестам из-за характера методов установки; наличие фиктивного поля тестового класса дает понять, какова область фиктивного.

person Rogério    schedule 31.01.2014
comment
Это ограничение TestNG? Может ли это быть функцией JMockit в будущем? - person Hamid Nazari; 31.01.2014
comment
Нет, это выбор дизайна в JMockit. - person Rogério; 31.01.2014

Динамическое частичное имитация — еще один метод для указания @Mocked зависимости локально. Однако у него есть свои ограничения (см. комментарии ниже).

person mucaho    schedule 20.02.2014
comment
Что ж, Dynamic Partial Mocking можно использовать, но, как указано в документации, у него есть ограничения: If the Class object for a given class is passed, the methods and constructors defined in that class are considered for mocking, but not the methods and constructors of its super-classes. В моем случае у меня нет доступа к внутренней зависимости для ее внедрения (это глубоко похоронено), и использование типа класса делает не предоставить то, что мне нужно, либо. - person Hamid Nazari; 24.02.2014
comment
Вас устроит прохождение инстанса? If an instance of a given class is passed, then all methods defined in the whole class hierarchy, from the concrete class of the given instance up to (but not including) Object, are considered for mocking; the constructors of these classes, however, are not (since an instance was already created). - person mucaho; 24.02.2014