O Xunit tem um recurso interessante : você pode criar um teste com um Theory
atributo e colocar dados nos InlineData
atributos, e o xUnit irá gerar muitos testes e testar todos eles.
Eu quero ter algo como isto, mas os parâmetros para o meu método não são 'dados simples' (como string
, int
, double
), mas uma lista de minha classe:
public static void WriteReportsToMemoryStream(
IEnumerable<MyCustomClass> listReport,
MemoryStream ms,
StreamWriter writer) { ... }
c#
unit-testing
xunit
xunit.net
zchpit
fonte
fonte
Respostas:
Existem muitos
xxxxData
atributos no XUnit. Verifique por exemplo oPropertyData
atributo.Você pode implementar uma propriedade que retorna
IEnumerable<object[]>
. Cada umobject[]
que este método gera será então "desempacotado" como um parâmetro para uma única chamada para o seu[Theory]
método.Outra opção é
ClassData
, que funciona da mesma forma, mas permite compartilhar facilmente os 'geradores' entre os testes em diferentes classes / namespaces, e também separa os 'geradores de dados' dos métodos de teste reais.Veja, por exemplo, estes exemplos aqui :
Exemplo de PropertyData
Exemplo de ClassData
fonte
static
. É exatamente por isso que eu não faria. ClassData é quando você deseja escapar da estática. Ao fazer isso, você pode reutilizar (ou seja, aninhar) os geradores mais facilmente.[MemberData("{static member}", MemberType = typeof(MyClass))]
para substituir oClassData
atributo.nameof
palavra - chave em vez de codificar um nome de propriedade (quebra facilmente, mas silenciosamente).Para atualizar a resposta de @Quetzalcoatl: O atributo
[PropertyData]
foi substituído pelo[MemberData]
que leva como argumento o nome da string de qualquer método estático, campo ou propriedade que retorna umIEnumerable<object[]>
. (Acho particularmente bom ter um método iterador que pode realmente calcular os casos de teste um de cada vez, gerando-os à medida que são calculados.)Cada elemento na sequência devolvida pelo enumerador é um
object[]
e cada array deve ter o mesmo comprimento e esse comprimento deve ser o número de argumentos para o seu caso de teste (anotado com o atributo[MemberData]
e cada elemento deve ter o mesmo tipo que o parâmetro do método correspondente . (Ou talvez possam ser do tipo conversível, não sei.)(Consulte as notas de lançamento para xUnit.net março de 2014 e o patch real com código de exemplo .)
fonte
Criar matrizes de objetos anônimos não é a maneira mais fácil de construir os dados, então usei esse padrão em meu projeto
Primeiro defina algumas classes reutilizáveis e compartilhadas
Agora seu teste individual e dados de membro são mais fáceis de escrever e mais limpos ...
A
Description
propriedade string serve para atirar em si mesmo quando um de seus muitos casos de teste falharfonte
Suponha que temos uma classe Car complexa que tem uma classe Fabricante:
Vamos preencher e passar na classe Carro para um teste de Teoria.
Portanto, crie uma classe 'CarClassData' que retorna uma instância da classe Car como a seguir:
É hora de criar um método de teste (CarTest) e definir o carro como parâmetro:
Boa sorte
fonte
Você pode tentar desta forma:
Crie outra classe para conter os dados de teste:
fonte
Para minhas necessidades, eu só queria executar uma série de 'usuários de teste' por meio de alguns testes - mas [ClassData] etc. parecia um exagero para o que eu precisava (porque a lista de itens foi localizada para cada teste).
Então, fiz o seguinte, com uma matriz dentro do teste - indexada de fora:
Isso atingiu meu objetivo, mantendo a intenção do teste clara. Você só precisa manter os índices sincronizados, mas isso é tudo.
Parece bom nos resultados, é recolhível e você pode executar novamente uma instância específica se receber um erro:
fonte
MemberData
parece ser que você não pode ver nem executar o teste com uma entrada de teste específica. É uma merda.MemberData
se você usarTheoryData
e opcionalmenteIXunitSerializable
. Mais informações e exemplos aqui ... github.com/xunit/xunit/issues/429#issuecomment-108187109Assim resolvi o seu problema, tive o mesmo cenário. Então, inline com objetos personalizados e um número diferente de objetos em cada execução.
Portanto, este é meu teste de unidade, observe o parâmetro params . Isso permite enviar um número diferente de objetos. E agora minha classe DeviceTelemetryTestData :
Espero que ajude !
fonte
Eu acho que você se enganou aqui. O que o
Theory
atributo xUnit realmente significa: você deseja testar esta função enviando valores especiais / aleatórios como parâmetros que esta função em teste recebe. Isso significa que o que você define como o próximo atributo, como:InlineData
,PropertyData
,ClassData
, etc .. será a fonte para esses parâmetros. Isso significa que você deve construir o objeto de origem para fornecer esses parâmetros. No seu caso, acho que você deve usar oClassData
objeto como fonte. Além disso - observe queClassData
herda de:IEnumerable<>
- isso significa que cada vez que outro conjunto de parâmetros gerados será usado como parâmetros de entrada para a função em teste atéIEnumerable<>
produzir valores.Exemplo aqui: Tom DuPont .NET
O exemplo pode estar incorreto - eu não usei o xUnit por muito tempo
fonte