Pergunta

Eu estou usando JMockit para teste de unidade (com TestNG), e estou tendo problemas com a classe expectativas para zombar de um método que utiliza um tipo primitivo (booleano) como um parâmetro, usando um combinador. Aqui está um código de exemplo que ilustra o problema.

/******************************************************/
import static org.hamcrest.Matchers.is;

import mockit.Expectations;

import org.testng.annotations.Test;

public class PrimitiveMatcherTest {
  private MyClass obj;

  @Test
  public void testPrimitiveMatcher() {
    new Expectations(true) {
      MyClass c;
      {
        obj = c;
        invokeReturning(c.getFoo(with(is(false))), "bas");
      }
    };

    assert "bas".equals(obj.getFoo(false));

    Expectations.assertSatisfied();
  }

  public static class MyClass {
    public String getFoo(boolean arg) {
      if (arg) {
        return "foo";
      } else {
        return "bar";
      }
    }
  }
}
/******************************************************/

A linha que contém a chamada para invokeReturning (...) lança uma NullPointerException.

Se eu mudar esta chamada para não usar uma correspondência, como em:

invokeReturning(c.getFoo(false), "bas");

ele funciona muito bem. Isso não é bom para mim, porque no meu código real eu realmente estou zombando de um método multi-parâmetro e eu preciso usar uma correspondência em outro argumento. Neste caso, a classe expectativas exige que todas argumentos usar uma correspondência.

Eu tenho certeza que este é um bug, ou talvez não seja possível usar Matchers com tipos primitivos (que me deixam triste). Alguém já encontrou este problema, e sabe como contornar isso?

Foi útil?

Solução 2

Então, o problema parece estar em Expectations.with ():

   protected final <T> T with(Matcher<T> argumentMatcher)
   {
      argMatchers.add(argumentMatcher);

      TypeVariable<?> typeVariable = argumentMatcher.getClass().getTypeParameters()[0];

      return (T) Utilities.defaultValueForType(typeVariable.getClass());
   }

A chamada para typeVariable.getClass () não faz o que os espera autor, ea chamada para Utilities.defaultValueFor tipo retorna nulo. O de-autoboxing de volta o valor booleano primitivo é onde o NPE vem.

Eu fixo-lo mudando o invokeReturning (...) chamada para:

invokeReturning(withEqual(false)), "bas");

Eu não estou mais usando uma correspondência aqui, mas é bom o suficiente para o que eu preciso.

Outras dicas

a questão é a combinação do uso de Expectativa e faz isso Matchers não suporta tipo primitivo.

O código Matchers contar com genérico que basicamente não suporta tipo primitivo. Tipicamente, o uso de Matchers é mais para o valor correspondente; com a auto-boxing / unboxing feater em Java 5, isso geralmente não é um problema.

Mas Expectativa de JMockit é não usá-lo para o valor coincidentes, ele usa-lo para algum tipo de análise para determinar a assinatura type..which chamada de método, neste caso, os Matchers vai resultou em tipo booleano, enquanto o seu método é tipo primitivo .. por isso deixa de zombe-lo corretamente.

Eu sinto muito que eu não posso te dizer qualquer solução para este. Talvez alguém pode ajudar.

Eu mudei JMockit (liberação de 0,982), de modo que "com (é (false))" e outras variações semelhantes agora trabalho como esperado (já não nula retornos, mas o valor do argumento real dentro do combinador interno).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top