Qual é a maneira idiomática de verificar o tamanho da coleção no xUnit?

111

Eu tenho em meu conjunto de testes um teste mais ou menos assim:

[Fact]
public void VerifySomeStuff()
{
    var stuffCollection = GetSomeStuff();

    Assert.Equal(1, stuffCollection.Count());
}

Este teste funciona como eu esperava, mas quando eu o executo, o xUnit imprime um aviso:

aviso xUnit2013: Não use Assert.Equal () para verificar o tamanho da coleção.

No entanto, nenhuma alternativa é sugerida no aviso, e uma pesquisa no Google me leva ao código-fonte em xUnit para o teste que verifica se esse aviso foi impresso.

Se Assert.Equal()não é a maneira correta de verificar o comprimento de uma coleção, qual é?


Para esclarecer: eu percebi que poderia "enganar" o xUnit para não emitir esse aviso, por exemplo, extraindo uma variável ou usando Assert.True(stuff.Count() == 1). O último é apenas hacky, e o primeiro parece que se o xUnit está, por exemplo, tentando evitar múltiplas iterações de um IEnumerable<T>, então este é o caminho errado a seguir (porque vou obter dicas do compilador sobre isso separadamente se for um problema), e xUnit em si nunca deve ter que avaliar a entrada mais de uma vez (na verdade, provavelmente obterá a mesma entrada, independentemente da extração de variável, por causa de como funciona a chamada de função C #).

Portanto, não estou apenas interessado em remover esse aviso de minha saída. Uma resposta à minha pergunta também explica por que esse aviso está incluído na biblioteca em primeiro lugar e por que qualquer abordagem que eu deveria usar é melhor.

Tomas Aschan
fonte
se você armazenar stuffCollection.Count()em uma variável separada e passá-la para o assert, terá o mesmo erro?
hellyale,
Talvez este ?
Uwe Keim,

Respostas:

112

O Xunit oferece soluções rápidas para a maioria de seus avisos, então você deve ser capaz de ver o que ele considera "certo".

xunit

No seu caso, ele quer que você use, Assert.Singlejá que está esperando exatamente um item. Se você estivesse declarando um número arbitrário, como 412, não seria um aviso sobre o uso Count. Ele só irá sugerir o uso Singlese você estiver esperando um item ou Emptyse não estiver esperando nenhum item.

vcsjones
fonte
6
Obrigado, isso faz sentido. FWIW, eu estava vendo isso ao compilar no VS Code, onde a ação rápida não apareceu, então incluir a sugestão de correção na mensagem de aviso teria sido muito mais útil.
Tomas Aschan,
2
@TomasLycken - ah. Sim, há um problema para isso aqui: github.com/xunit/xunit/issues/1423
vcsjones
5
Não sou fã desse comportamento; às vezes, a contagem 1 é apenas acidental e parece menos expressivo impor a chamada para .Single (). O teste pode mudar para esperar uma contagem diferente e parece irritante ter que fazer a mudança para chamar um método completamente diferente em vez de apenas mudar um número.
vargonian de
2
Único é legal para um item único, eu tenho 3 itens e não quero escrever Assert.Collection completo, xUnit tem Assert.Triple? haha
Pawel Cioch
1
@PawelCioch de acordo com xunit.net/xunit.analyzers/rules/xUnit2013.html eles têm Empty, Singlee NotEmpty- se você espera um valor dinâmico xUnit2013 não deve ser acionado.
mbx
2

Eu descobri que isso me dá o mesmo erro:

Assert.Equal(2, vm.Errors.Count());

E lançá-lo impediu o erro de aparecer.

Assert.Equal(2, (int)vm.Errors.Count());
devjc
fonte
2
Tenho certeza de que esta não é a forma ideomática .
mbx
1

Para um único elemento em uma lista, é melhor usar isso: Assert.Single(resultList);

Bosco Han
fonte
-1

Eu tive o mesmo problema quando usei a propriedade Count conforme abaixo no xUnit.

insira a descrição da imagem aqui

Depois de usar a função Count () na coleção, meu problema foi corrigido.

Bhuwan Maharjan
fonte
Corrigido o problema, mas você ainda não usa o XUnit como deveria!
Daniel Eisenreich
8
@DanielEisenreich qual é a maneira correta de declarar a contagem para um número específico se for maior que 1?
SomeGuyOnAComputer
@SomeGuyOnAComputer e os outros 4 votos positivos. Esqueça o que eu disse, fui muito atrevido. Se for maior, você não tem outra escolha.
Daniel Eisenreich