2013-04-16 3 views
34

У меня есть класс java, полный методов void, и я хочу сделать некоторый модульный тест, чтобы получить максимальный охват кода.JUNIT test void methods

Например, у меня есть этот метод:

protected static void checkifValidElements(int arg1, int arg2) { 
    method1(arg1); 
    method2(arg1); 
    method3(arg1, arg2); 
    method4(arg1, arg2); 
    method5(arg1); 
    method6(arg2); 
    method7(); 
} 

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

Пример:

private static void method1(arg1) { 
    if (arg1.indexOf("$") == -1) { 

     //Add an error message 
     ErrorFile.errorMessages.add("There is a dollar sign in the specified parameter"); 
    } 
} 

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

Единственный способ я вижу, чтобы изменить этот метод, чтобы вернуть Int или bollean значение, например:

protected static int checkifValidElements(int arg1, int arg2) { 
    method1(arg1); 
    method2(arg1); 
    method3(arg1, arg2); 
    method4(arg1, arg2); 
    method5(arg1); 
    method6(arg2); 
    method7(); 
    return 0; 
} 

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

+0

Я не понимаю, как тип возвращаемого значения метода влияет на охват. Утверждения также не имеют отношения к охвату. Единственный факт - вы используете метод во время модульного теста или нет. – kan

ответ

43

Я хочу сделать некоторые модульное тестирование, чтобы получить максимальное покрытие кодовой

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

но я не вижу, как я могу проверить свой метод checkIfValidElements, он ничего не возвращает или ничего не меняет.

Ну вы, вероятно, следует дать несколько тестов, которые между ними проверить, что все 7 методы называются соответственно - как с неверным аргументом и с действительным аргументом, проверяя результаты ErrorFile каждый раз.

Например, предположим, что кто-то удалил вызов:

method4(arg1, arg2); 

... или случайно изменили порядок аргументов:

method4(arg2, arg1); 

Как бы вы замечаете эти проблемы? Идите от этого и спроектируйте тесты, чтобы доказать это.

+0

Спасибо! Я все еще новичок в модульном тестировании, и я слишком много думаю о линейном/сложном способе. Я упрощу тесты и проведу тест, чтобы получить больше «охвата» или возможных случаев тестов. – metraon

+0

«Кодовое покрытие никогда не должно быть целью написания модульных тестов». Не могли бы вы объяснить немного более деатилированный? – Gobliins

+6

@Gobliins: Покрытие кода - это число. Если число будет расти, если вы не будете больше доверять надежности своего кода, в чем смысл? Целью должно быть улучшение качества кода (как для разработки, так и для реализации). Охват - это один * возможный * индикатор этого, но вполне возможно иметь хорошие тесты для критических и сложных аспектов вашего кода и по-прежнему иметь относительно низкий охват - или иметь высокий охват, но плохие тесты. –

3

Вы по-прежнему можете протестировать метод void, утверждая, что он имеет соответствующий побочный эффект. В вашем method1 Например, устройство тест может выглядеть примерно так:

public void checkIfValidElementsWithDollarSign() { 
    checkIfValidElement("$",19); 
    assert ErrorFile.errorMessages.contains("There is a dollar sign in the specified parameter"); 
} 
1

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

15

Если ваш метод не имеет побочных эффектов и ничего не возвращает, значит, он ничего не делает.

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

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

В вашем примере вы вызываете статические методы из своих невозвратных функций, что делает его сложным, если вы не можете проверить, что результат всех этих статических методов правильный. Лучший способ - с точки зрения тестирования - вводить фактические объекты в том, что вы вызываете методы. Затем вы можете использовать что-то вроде EasyMock или Mockito для создания Mock Object в своем модульном тесте и вводить макет объекта в класс. Затем Mock Object позволяет утверждать, что были вызваны правильные функции с правильными значениями и в правильном порядке.

Например:

private ErrorFile errorFile; 

public void setErrorFile(ErrorFile errorFile) { 
    this.errorFile = errorFile; 
} 

private void method1(arg1) { 
    if (arg1.indexOf("$") == -1) { 

     //Add an error message 
     errorFile.addErrorMessage("There is a dollar sign in the specified parameter"); 
    } 
} 

Тогда в тесте вы можете написать:

public void testMethod1() { 
    ErrorFile errorFile = EasyMock.createMock(ErrorFile.class); 
    errorFile.addErrorMessage("There is a dollar sign in the specified parameter"); 
    EasyMock.expectLastCall(errorFile); 
    EasyMock.replay(errorFile); 

    ClassToTest classToTest = new ClassToTest(); 
    classToTest.setErrorFile(errorFile); 
    classToTest.method1("a$b"); 

    EasyMock.verify(errorFile); // This will fail the test if the required addErrorMessage call didn't happen 
} 
+0

Я буду копаться в этом. Спасибо – metraon

+1

<< Если ваш метод не имеет побочных эффектов и ничего не возвращает, значит, он ничего не делает. >> Это неправда, что, если ваш метод просто изменяет состояние объекта? – magulla

+7

Это побочный эффект, он что-то меняет – tddmonkey

1

Вы можете узнать что-то, называемое «насмешкой». Вы можете использовать это, например, для проверки: - функция была вызвана - функция была вызвана x раз - функция была вызвана как минимум x раз - функция вызывалась с определенным набором параметров. В вашем случае, например, вы можете использовать насмешку, чтобы проверить, что метод3 был вызван один раз с тем, что вы передаете как arg1 и arg2.

Посмотрите на эти: https://code.google.com/p/mockito/ https://code.google.com/p/powermock/