Как изменить метод, чтобы облегчить тестирование - PullRequest
0 голосов
/ 05 сентября 2011

Ниже приведен метод, который мне трудно понять, как тестировать с использованием JUnit.
Этот метод сложно протестировать, поскольку он зависит от результатов других методов (например, getClosestDcoumentCode).

Исходя из моего прочтения JUnit, это говорит о том, что я должен рефакторинг метода.Но как?И если рефакторинг не нужен, как вы тестируете метод, который зависит от других методов?

Спасибо,

Elliott

private static String findPrincipal(List<DocumentKey> documentkeys_) {
    Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>();
    for (DocumentKey document : documentkeys_) {
        int x = 0;
        String closestCode = getClosestDocumentCode(document.candidates);
        if (closestCode == null) continue;
        int thecount = 0;
        if (codecounts.containsKey(closestCode))
            thecount = codecounts.get(closestCode);
        if (document.hasKey)
            thecount += 2;
        else
            thecount++;
        codecounts.put(closestCode, new Integer(thecount));
        x++;

    }
    String closestCode = getClosestCode(codecounts);
    return closestCode;
}

Ответы [ 4 ]

7 голосов
/ 05 сентября 2011

Ну, во-первых, мне интересно, действительно ли метод должен быть статическим, и что делает этот класс. Похоже, что это может быть класс БОГА, или, по крайней мере, он нарушает принцип единственной ответственности. Что делает getClosestCode? Если бы это был класс, вы могли бы внедрить его с заглушкой в ​​ваших тестах в тестовый класс.

EasyMock позволит вам высмеивать ответ метода, но я не уверен, как вы высмеиваете статические методы.

В общем, вам, вероятно, нужно

  1. Извлечение длинных функций в классы
  2. Сделать функциональность нестатичной
  3. Сохранение единого принципала ответственности
5 голосов
/ 05 сентября 2011

Мне кажется, что getClosestCode и getClosestDocumentCode относятся к другому набору обязанностей , чем findPrincipal метод. Итак, вы хотите начать с разделения их на два разных класса. Создайте интерфейс для каждого класса для реализации. Класс, который реализует метод findPrincipal, может затем полагаться на другой интерфейс в качестве аргумента конструктора, например:

public class PrincipalFinderImpl implements PrincipalFinder
{
    private CodeFinder codeFinder;
    public PrincipalFinderImpl(CodeFinder codeFinder) {
        this.codeFinder = codeFinder;
    }
    public String findPrincipal(List<DocumentKey> documentkeys_) {
        Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>();
        for (DocumentKey document : documentkeys_) {
            int x = 0;
            String closestCode = codeFinder.getClosestDocumentCode(document.candidates);
            if (closestCode == null) continue;
            int thecount = 0;
            if (codecounts.containsKey(closestCode))
                thecount = codecounts.get(closestCode);
            if (document.hasKey)
                thecount += 2;
            else
                thecount++;
            codecounts.put(closestCode, new Integer(thecount));
            x++;

        }
        String closestCode = codeFinder.getClosestCode(codecounts);
        return closestCode;
    }
}

Теперь должно быть легко создать другой класс, реализующий интерфейс CodeFinder, либо вручную, либо с использованием инфраструктуры Mocking. Затем вы можете контролировать результаты каждого вызова getClosestCode и getClosestDocumentCode и убедиться, что каждый из этих методов вызывается именно с теми аргументами, с которыми вы ожидаете вызова.

0 голосов
/ 05 сентября 2011

Я не читаю метод глубоко. Но если частный метод нуждается в тестировании, это указывает на что-то не так с вашим дизайном. По крайней мере, Кент Бек так думает .

0 голосов
/ 05 сентября 2011

Существует глава о вызовах-заглушках на JUnit Second Edition , я рекомендую вам взглянуть на это, если вы считаете, что ваши существующие коды не написаны для стандартов разработки, управляемых тестом.

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