Obtendo “NoSuchMethodError: org.hamcrest.Matcher.describeMismatch” ao executar o teste no IntelliJ 10.5

Estou usando o JUnit-dep 4.10 e o Hamcrest 1.3.RC2.

Eu criei um correspondente personalizado que se parece com o seguinte:

public static class MyMatcher extends TypeSafeMatcher { @Override protected boolean matchesSafely(String s) { /* implementation */ } @Override public void describeTo(Description description) { /* implementation */ } @Override protected void describeMismatchSafely(String item, Description mismatchDescription) { /* implementation */ } } 

Ele funciona perfeitamente quando executado a partir da linha de comando usando Ant. Mas quando executado a partir do IntelliJ, ele falha com:

 java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:18) at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8) at com.netflix.build.MyTest.testmyStuff(MyTest.java:40) 

Meu palpite é que está usando o hamcrest errado.MatcherAssert. Como faço para encontrar qual hamcrest.MatcherAssert está usando (ou seja, qual arquivo jar ele está usando para hamcrest.MatcherAssert)? AFAICT, o único jarro de hamcrest no meu classpath é o 1.3.RC2.

O IntelliJ IDEA está usando sua própria cópia do JUnit ou Hamcrest?

Como faço para a saída do tempo de execução CLASSPATH que o IntelliJ está usando?

Certifique-se de que o flask mais duro esteja mais alto na ordem de importação do que o seu jarro JUnit .

O JUnit vem com sua própria class org.hamcrest.Matcher que provavelmente está sendo usada no lugar.

Você também pode fazer o download e usar o junit-dep-4.10.jar, que é JUnit sem as classs mais antigas.

O mockito também tem as classs mais antigas, então você pode precisar mover também

Esse problema também surge quando você tem mockito-all em seu caminho de class, que já está obsoleto.

Se possível, inclua mockito-core .

Configuração Maven para misturar junit, mockito e hamcrest:

   org.hamcrest hamcrest-core 1.3 test   org.hamcrest hamcrest-library 1.3 test   org.mockito mockito-all 1.9.5 test   junit junit 4.11 test   

O problema era que a hamcrest.Matcher errada do hamcrest.Matcher , não do hamcrest.MatcherAssert , estava sendo usada. Isso estava sendo extraído de uma dependência do junit-4.8 que uma das minhas dependencies estava especificando.

Para ver quais dependencies (e versões) estão incluídas de qual fonte durante o teste, execute:

 mvn dependency:tree -Dscope=test 

O seguinte deve ser o mais correto hoje. Note que junit 4.11 depende de hamcrest-core, então você não precisa especificar nada, mockito-all não pode ser usado, pois inclui (não depende de) hamcrest 1.1

  junit junit 4.11 test   org.mockito mockito-core 1.10.8 test   org.hamcrest hamcrest-core    

Isso funcionou para mim depois de lutar um pouco

  org.hamcrest hamcrest-all 1.3 test   org.mockito mockito-all 1.9.5 test   junit junit 4.11 test  

Experimentar

expect(new ThrowableMessageMatcher(new StringContains(message)))

ao invés de

expectMessage(message)

Você pode gravar um método ExpectedException ou utilitário personalizado para finalizar o código.

Eu sei que este é um segmento antigo, mas o que resolveu o problema para mim foi adicionando o seguinte aos meus arquivos build.gradle. Como já foi dito acima, há um problema de compatibilidade com mockito-all

Post possivelmente útil:

 testCompile ('junit:junit:4.12') { exclude group: 'org.hamcrest' } testCompile ('org.mockito:mockito-core:1.10.19') { exclude group: 'org.hamcrest' } testCompile 'org.hamcrest:hamcrest-core:1.3' 

Apesar do fato de que esta é uma questão muito antiga e, provavelmente, muitas das ideias acima mencionadas resolveram muitos problemas, ainda quero compartilhar a solução com a comunidade que resolveu meu problema.

Descobri que o problema era uma function chamada “hasItem” que eu estava usando para verificar se um JSON-Array contém um item específico. No meu caso, verifiquei um valor do tipo Long.

E isso levou ao problema.

De alguma forma, os Matchers têm problemas com valores do tipo Long. (Eu não uso JUnit ou Rest-Assured tanto assim idk. Exatamente porque, mas eu acho que os dados JSON retornados apenas contêm Inteiros.)

Então o que eu fiz para consertar o problema foi o seguinte. Ao invés de usar:

 long ID = ...; ... .then().assertThat() .body("myArray", hasItem(ID)); 

você só tem que converter para Integer. Então o código de trabalho ficou assim:

 long ID = ...; ... .then().assertThat() .body("myArray", hasItem((int) ID)); 

Essa provavelmente não é a melhor solução, mas eu só queria mencionar que a exceção também pode ser lançada por causa de tipos de dados errados / desconhecidos.

O que funcionou para mim foi excluir o grupo mais sério da compilation de teste do junit.

Aqui está o código do meu build.gradle:

 testCompile ('junit:junit:4.11') { exclude group: 'org.hamcrest' } 

Se você estiver executando o IntelliJ, pode ser necessário executar o gradle cleanIdea idea clean build para detectar as dependencies novamente.

Eu sei que essa não é a melhor resposta, mas se você não consegue fazer o classpath funcionar, esta é uma solução do plano B.

No meu classpath de teste, adicionei a seguinte interface com uma implementação padrão para o método describeMismatch.

 package org.hamcrest; /** * PATCH because there's something wrong with the classpath. Hamcrest should be higher than Mockito so that the BaseMatcher * implements the describeMismatch method, but it doesn't work for me. */ public interface Matcher extends SelfDescribing { boolean matches(Object item); default void describeMismatch(Object item, Description mismatchDescription) { mismatchDescription.appendDescriptionOf(this).appendValue(item); } @Deprecated void _dont_implement_Matcher___instead_extend_BaseMatcher_(); }