Pergunta

Eu tenho uma interface com um método que espera um array de Foo:

public interface IBar {
  void doStuff(Foo[] arr);
}

Estou zombando dessa interface usando o Mockito e gostaria de afirmar que doStuff() é chamado, mas não quero validar qual argumento foi passado - "não me importo".

Como escrevo o seguinte código usando any(), o método genérico, em vez de anyObject()?

IBar bar = mock(IBar.class);
...
verify(bar).doStuff((Foo[]) anyObject());
Foi útil?

Solução

Desde o Java 8 você pode usar o método sem argumentos any método e o argumento de tipo serão inferidos pelo compilador:

verify(bar).doStuff(any());

Explicação

A novidade no Java 8 é que o tipo de destino de uma expressão será usada para inferir parâmetros de tipo de suas subexpressões.Antes do Java 8, apenas argumentos para métodos eram usados ​​para inferência de parâmetros de tipo (na maioria das vezes).

Neste caso o tipo de parâmetro de doStuff será o tipo de destino para any(), e o tipo de valor de retorno de any() será escolhido para corresponder a esse tipo de argumento.


Tipos primitivos

Infelizmente, isso não funciona com tipos primitivos:

public interface IBar {
    void doPrimitiveStuff(int i);
}

verify(bar).doPrimitiveStuff(any()); // Compiles but throws NullPointerException
verify(bar).doPrimitiveStuff(anyInt()); // This is what you have to do instead

O problema é que o compilador irá inferir Integer como o valor de retorno de any().Mockito não estará ciente disso (devido ao apagamento de tipo) e retornará o valor padrão para tipos de referência, que é null.O tempo de execução tentará desembalar o valor de retorno chamando o método intValue método nele antes de passá-lo para doStuff, e a exceção é lançada.

Outras dicas

Isso deve funcionar

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

verify(bar).DoStuff(any(Foo[].class));

Você pode usar Mockito.isA() por isso:

import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.verify;

verify(bar).doStuff(isA(Foo[].class));

http://site.mockito.org/mockito/docs/current/org/mockito/matchers.html#isa(java.lang.class)

Como eu precisava usar esse recurso para o meu projeto mais recente (em um ponto, atualizamos a partir de 1.10.19), apenas para manter os usuários (que já estão usando o Mockito-core versão 2.1.0 ou maior) atualizados, os métodos estáticos das respostas acima devem ser retirados de ArgumentMatchers classe:

import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.any;

Lembre -se disso se você planeja manter seus artefatos do Mockito atualizados como possivelmente começando na versão 3, essa classe pode não existir mais:

De acordo com 2.1.0 e acima, Javadoc de org.mockito.matchers afirma:

Usar org.mockito.ArgumentMatchers. Esta aula agora está presa para evitar um nome de nome com hamcrest * org.hamcrest.Matchersclasse. Esta classe provavelmente será removida na versão 3.0.

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