2013-06-23 4 views
14

Я спрашиваю себя, насколько глубоко я должен проходить (подразделение), тестируя свои классы. Как пример, у меня следующий простой класс.Аннотации для тестирования модулей?

import javax.annotation.security.PermitAll; 
import javax.ejb.Singleton; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 


@Path(value = "ping") 
@Singleton 
@PermitAll 
public class PingRestService { 

    @GET 
    @Produces(MediaType.TEXT_PLAIN) 
    public String pingMethod(){ 
     return "pong"; 
    } 

} 

Я написал следующий тест блок:

import static org.junit.Assert.*; 
import java.lang.reflect.Method; 
import javax.annotation.security.PermitAll; 
import javax.ejb.Singleton; 
import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.core.MediaType; 

import org.junit.Test; 


public class PingRestServiceTest { 

    PingRestService prs = new PingRestService(); 

    @Test 
    public void testClassAnnotations(){ 
     assertEquals(3, prs.getClass().getAnnotations().length); 

     assertTrue(prs.getClass().isAnnotationPresent(PermitAll.class)); 
     assertTrue(prs.getClass().isAnnotationPresent(Singleton.class)); 
     assertTrue(prs.getClass().isAnnotationPresent(Path.class)); 

     assertEquals("ping", prs.getClass().getAnnotation(Path.class).value()); 

    } 

    @Test 
    public void testPingMethodAnnotations() throws SecurityException, NoSuchMethodException{ 

     Method method = prs.getClass().getDeclaredMethod("pingMethod"); 
     assertEquals(2, method.getAnnotations().length); 

     assertTrue(method.isAnnotationPresent(GET.class)); 
     assertTrue(method.isAnnotationPresent(Produces.class)); 

     assertEquals(1, method.getAnnotation(Produces.class).value().length); 
     assertEquals(MediaType.TEXT_PLAIN, method.getAnnotation(Produces.class).value()[0]); 
    } 

    @Test 
    public void testPingMethod() { 
     assertEquals("pong", prs.pingMethod()); 
    } 

} 

это имеет смысл? Или мне нужно только проверить возвращаемую строку («понг», testPingMethod), пропустить все тесты аннотаций (testClassAnnotations, testPingMethodAnnotations)?

Я думаю, что некоторые аннотации являются частью бизнес-логики (например, PermitAll) и поэтому должны быть протестированы.

+1

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

+1

Если вы добавите дополнительный тип мультимедиа в свою аннотацию @Produces, ваш тест прерывается, но вы не изменили никакой логики в тестируемом методе. Кажется, это бессмысленный тест и хрупкий. – JamesB

+0

, но если тест ломается, это плохо? Я имею в виду, я ожидаю, что этот метод создает только определенный тип медиа. Если я добавлю другой тип носителя, я должен настроить мои тесты. Это не хорошая практика? Тестирование чего-то вроде PermitAll может быть намного сложнее с помощью теста интеграции. Использование стандартного метода isnotationPresent классов Java можно было бы охватить в одной строке кода. – lappo

ответ

5

В большинстве случаев проверяется функциональность кода, а не способ его реализации. Это называется Black Box Testing (см .: http://en.wikipedia.org/wiki/Black-box_testing). При проведении теста вы должны спросить себя: «Каковы возможные входные значения устройства для тестирования и каковы ожидаемые результаты?» Теперь в тесте вы вызываете свой код с входными значениями и проверяете результат с ожидаемым, чтобы убедиться, что ваш код ведет себя так, как вы хотите. Со временем вы можете оптимизировать код, не изменяя функциональность. Тогда вам не нужно менять тест. Но вы можете повторно запустить его, чтобы убедиться, что он по-прежнему ведет себя одинаково. Даже если он реализован по-разному. Или вы можете внести изменения в детали реализации, которые имеют побочные эффекты для тестируемой вами функции. Также в этом случае вам не нужно менять тест, но вам просто нужно его повторно запустить. В вашем простом случае у вас нет ввода и одного статического вывода, поэтому вы можете просто вызвать метод и проверить, возвращается ли «понг». Но случаи реальной жизни, которые протестированы, редко бывают такими простыми.

Редактировать: вы можете увидеть, что настройки @PermitAll настраиваются и путь URL, который '@Path' настраивает как входные данные, а также проверяет их в тесте интеграции, как это предлагали «Борис Паук» и «Ави». Но другие аннотации являются специфическими для реализации.

3

На мой взгляд, эти аннотации - это аспекты вашего класса, а не суть его, его настоящая цель, поэтому его нельзя тестировать на единицу. Возможно, завтра вы будете использовать Spring MVC вместо JAX-RS, но ваш класс будет иметь такое же поведение, поэтому единичный тест должен быть таким же.