Como o Junit @Rule funciona?

195

Quero escrever casos de teste para uma grande parte do código, gostaria de saber detalhes do @Rulerecurso de anotação JUnit , para que eu possa usá-lo para escrever casos de teste. Forneça boas respostas ou links, que fornecem uma descrição detalhada de sua funcionalidade através de um exemplo simples.

Dipak
fonte
Achei que este artigo explica @Rulemuito bem, especialmente confira a última seção "A sequência dos eventos em detalhes"
Peter Perháč
Eu acho que é semelhante ao conceito de injeção, estou certo?
Chao
Obrigado por compartilhar esse link. Uma coisa não está clara. Quando é chamado o DEFAULT Statement.evaluate ()? É chamado antes da avaliação () de todas as regras ou depois de todas? Eu estou supondo depois de todos eles.
MasterJoe2
@ testerjoe2, você pode optar por ignorar completamente a declaração padrão. Você pode optar por delegar a ele ou simplesmente substituí-lo por alguma outra declaração sua. Não é chamado , você pode chamá-lo ou não. Esse foi o ponto 10: "O método Evalu () da instrução de captura de tela chama o método Evalu () da instrução padrão".
Peter Perháč

Respostas:

155

As regras são usadas para adicionar funcionalidades adicionais que se aplicam a todos os testes dentro de uma classe de teste, mas de uma maneira mais genérica.

Por exemplo, ExternalResource executa o código antes e depois de um método de teste, sem precisar usar @Beforee @After. Usar um ExternalResourceao invés de @Beforee @Afterdá oportunidades para uma melhor reutilização de código; a mesma regra pode ser usada em duas classes de teste diferentes.

O design foi baseado em: Interceptores no JUnit

Para mais informações, consulte wiki do JUnit: Rules .

Matthew Farwell
fonte
1
Correção: "Por exemplo, ExternalResource executa o código antes e depois de uma classe de teste ." Há algo sobre o uso de apply () para que o ExternalResource seja executado entre testes.
derekm 12/07
62

As regras do Junit trabalham com o princípio da AOP (programação orientada a aspectos). Ele intercepta o método de teste, oferecendo a oportunidade de fazer algumas coisas antes ou depois da execução de um método de teste específico.

Veja o exemplo do código abaixo:

public class JunitRuleTest {

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void testRule() throws IOException {
    File newFolder = tempFolder.newFolder("Temp Folder");
    assertTrue(newFolder.exists());
  }
} 

Sempre que o método de teste acima é executado, uma pasta temporária é criada e é excluída após a execução do método. Este é um exemplo de uma regra pronta para uso fornecida pela Junit.

Comportamento semelhante também pode ser alcançado criando nossas próprias regras. O Junit fornece a interface TestRule, que pode ser implementada para criar nossa própria regra de junit.

Aqui está um link útil para referência:

Abhishek Mohanty
fonte
4
para que seja excluído sem escrever nenhum código para excluir / limpar o objeto?
Dror
observe a fonte do github.com/junit-team/junit4/blob/master/src/main/java/org/… , a pasta é criada no método de retorno de chamada before () e excluída no método de retorno de chamada after (). ..
Pierluigi Vernetto
1
Para pessoas que talvez não tenham entendido por que o TemporaryFolder é excluído, é porque é um TemporaryFolder fornecido pela Junit para servir como uma pasta temporária que é excluída automaticamente - ou seja, a etapa de desmontagem faz parte da própria classe TemporaryFolder.
Mindaugas Bernatavičius
17

tl; dr para saber como funciona: JUnit agrupa seu método de teste em um objeto Statement para que statement.Execute () execute seu teste. Em vez de chamar o statement.Execute () diretamente para executar seu teste, o JUnit passa o Statement para um TestRule com a anotação @Rule. A função "aplicar" do TestRule retorna uma nova instrução, dada a instrução com seu teste. O novo método Execute () da instrução pode chamar o método de execução da instrução de teste (ou não, ou chamá-lo várias vezes) e fazer o que quiser antes e depois. Agora, o JUnit possui uma nova instrução que faz mais do que apenas executar o teste, e pode passar novamente a outras regras antes de finalmente chamar Execute.

Alexander Taylor
fonte
2
A instrução tem um método de avaliação não executado.
Hemanth 18/07/19
0

As regras são usadas para aprimorar o comportamento de cada método de teste de maneira genérica. A regra Junit intercepta o método de teste e nos permite fazer algo antes que um método de teste inicie a execução e depois que um método de teste foi executado.

Por exemplo, usando a regra @Timeout , podemos definir o tempo limite para todos os testes.

public class TestApp {
    @Rule
    public Timeout globalTimeout = new Timeout(20, TimeUnit.MILLISECONDS);

    ......
    ......

 }

A regra @TemporaryFolder é usada para criar pastas e arquivos temporários. Toda vez que o método de teste é executado, uma pasta temporária é criada e é excluída após a execução do método.

public class TempFolderTest {

 @Rule
 public TemporaryFolder tempFolder= new TemporaryFolder();

 @Test
 public void testTempFolder() throws IOException {
  File folder = tempFolder.newFolder("demos");
  File file = tempFolder.newFile("Hello.txt");

  assertEquals(folder.getName(), "demos");
  assertEquals(file.getName(), "Hello.txt");

 }


}

Você pode ver exemplos de algumas regras internas fornecidas por junit neste link .

Hari Krishna
fonte