2010-10-12 1 views
4

Я бы хотел, чтобы тестовый класс JUnit 4 реализовал тот же интерфейс, что и класс его тестирования. Таким образом, по мере изменения интерфейса (и он будет, мы будем в раннем развитии) компилятор гарантирует, что соответствующие методы добавляются в тестовый класс. Например:Методы непустых тестов в JUnit 4

public interface Service { 
    public String getFoo(); 
    public String getBar(); 
} 

public class ServiceImpl implements Service { 
    @Override public String getFoo() { return "FOO"; } 
    @Override public String getBar() { return "BAR"; } 
} 

public class ServiceTest implements Service { 
    @Override 
    @Test 
    public String getFoo() { 
    //test stuff 
    } 

    @Override 
    @Test 
    public String getBar() { 
    //test stuff 
    } 
} 

Когда я пытаюсь это, я получаю сообщение об ошибке: «java.lang.Exception: Метод getFoo() должен быть недействительным», предположительно потому, что методы испытаний должны возвращать ничтожным. Кто-нибудь знает об этом?

+1

Как бы принудительно реализовать этот метод через гарантию интерфейса каким-либо образом его тестируют? Поскольку вы пытаетесь использовать компилятор, чтобы гарантировать покрытие теста, так сказать ... Но отдельный экземпляр из класса производственного класса, реализующего один и тот же интерфейс, не гарантирует проверку. Это гарантирует соблюдение интерфейса. –

+0

Ну, правда, это гарантирует, что метод был добавлен в тестовый класс для каждого метода службы. Это не гарантирует, что метод действительно проверяет что-либо. Честно говоря, ни один из инструментов покрытия кода не имеет, так как вы можете использовать весь код и ничего не утверждать. Я просто хочу предупредить разработчика (разработчиков) о том, что есть замечательные тесты для рассмотрения. – romacafe

+0

Посмотрите на PMD http://pmd.sourceforge.net/rules/junit.html, в частности, правило JUnitTestsShouldIncludeAssert. – TofuBeer

ответ

7

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

В любом случае, вы можете использовать специальный бегун. Например:

@RunWith(CustomRunner.class) 
public class AppTest { 

    @Test 
    public int testApp() { 
    return 0; 
    } 
} 

public class CustomRunner extends JUnit4ClassRunner { 

    public CustomRunner(Class<?> klass) throws InitializationError { 
    super(klass); 
    } 

    protected void validate() throws InitializationError { 
    // ignore 
    } 
} 
+0

Ницца! Это именно то, что я ищу. Пока нет проверки, потому что я не совсем понял, как это работает. По крайней мере, пока ... Его жалоба на то, что «Custom runner class CustomRunner должен иметь открытый конструктор с подписью CustomRunner (Class testClass)». Но это так ... Поэтому я немного задумываюсь, чтобы попытаться заставить его работать. Оставайтесь с нами ... – romacafe

+0

Вы поместили класс CustomRunner в отдельный файл? Я запускаю этот пример в своей среде IDE перед публикацией здесь. –

+0

Это сделало трюк, спасибо. Теперь есть проблема с методами, которые принимают параметр из-за отражения, но это другая проблема. Большое спасибо! – romacafe

1

Более естественный путь, вероятно, будет использовать инструмент покрытия кода, такие как Cobertura. Он отлично интегрируется с JUnit И показывает случаи, когда ваши тесты могут быть недостаточными в некоторых случаях (есть много случаев, когда такой инструмент не поймает).