Java Модульное тестирование - макет всех методов класса для возврата одного результата - PullRequest
0 голосов
/ 03 апреля 2020

Я хотел бы смоделировать ВСЕ методы в классе, чтобы они возвращали один результат, вместо того, чтобы проверять каждый в отдельности, что-то вроде:

mock(Foo.class, allMethodsWithAnyArgs).thenReturn('abc');

Я очень новичок в Java тестировании, поэтому, пожалуйста, прости тупой вопрос. В этом гигантском проекте есть Mockito, PowerMockito, PowerMock, EasyMock и, возможно, другие вещи, поэтому я могу использовать все, что порекомендовано.

В расширенном примере будет что-то вроде этого, где мне нужно протестировать Foo:

public class Foo {
    doSomething(){
        Bar bar = new bar();

        // some code

        bar.x(a);

        // some code

        bar.x(a, b, c);

        // some more code

        bar.y(...);

        // even more code

        bar.z(...);
    }
}

Мне нужно заглушить все вызовы в баре, но мне плевать на возвращение, или я хочу получить одинаковый возврат, скажем, 1 или «хорошо» для всех из них и т. Д. c.

ОБНОВЛЕНИЕ: я согласен, что это не лучший код для тестирования, вот обновленный пример того, что я пытаюсь протестировать в этом случае, поэтому мне нужно заглушить MyUtil и методы bar, это stati c, так как Вы предлагаете мне их рефакторинг? Для меня не имеет смысла указывать MyUtil в качестве обязательного аргумента, и я бы предпочел оставить Foo как всегда c, если это возможно. Рабочий тестовый файл был бы очень признателен, так как я уже несколько дней борюсь с подобными вещами.

public class Foo {
    public static Object doSomething(Long id){
        Bar bar = new Bar();
        Object obj;

        if(somecondition) {
            Long vnumber = MyUtil.getVNumber(id);

            obj = bar.getCurrentObj(id, vnumber);            
        } else {
            obj = bar.getPreviousObj(id);
        }

        bar.z(obj);
        ....
    }
}

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

1 Ответ

1 голос
/ 05 апреля 2020

Наличие большого количества методов для имитации может быть признаком класса с слишком большим количеством обязанностей.

Однако, макеты не являются единственными тестами, удваивающимися . Что может лучше подойти для вашего случая использования - это подделка .

Это действительно будет зависеть от того, что Foo находится за интерфейсом:

interface Bar {


   String x(String s);


   String y(String s);
}

, тогда у вас есть реализация prod:

class RealBar implements Bar {

    @Override
    String x(String s) {
        // whatever your production logic is
    }
}

, а затем фальшивка, которую вы используете в тесте, который находится в вашем test исходном наборе:

class FakeBar implements Bar {

    @Override
    String x(String s) {
        return "abc";
    }
}

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

Если вы используете инжектор конструктора в Foo, ваш тест будет состоять из прохождения вашего поддельного Bar вместо производственного Bar

@Before
public void setUp() {
   foo = new Foo(new FakeBar());
}

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...