Xunit tiene una característica interesante : puede crear una prueba con un Theory
atributo y poner datos en InlineData
atributos, y xUnit generará muchas pruebas y las probará todas.
Quiero tener algo como esto, pero los parámetros a mi método no son 'simples datos' (como string
, int
, double
), sino una lista de mi clase:
public static void WriteReportsToMemoryStream(
IEnumerable<MyCustomClass> listReport,
MemoryStream ms,
StreamWriter writer) { ... }
c#
unit-testing
xunit
xunit.net
zchpit
fuente
fuente
Respuestas:
Hay muchos
xxxxData
atributos en XUnit. Mira, por ejemplo, elPropertyData
atributo.Puede implementar una propiedad que regrese
IEnumerable<object[]>
. Cada uno de losobject[]
que genera este método se "descomprimirá" como parámetros para una única llamada a su[Theory]
método.Otra opción es
ClassData
, que funciona igual, pero permite compartir fácilmente los 'generadores' entre pruebas en diferentes clases / espacios de nombres, y también separa los 'generadores de datos' de los métodos de prueba reales.Vea, es decir, estos ejemplos de aquí :
Ejemplo de PropertyData
Ejemplo de ClassData
fuente
static
. Eso es exactamente por lo que no lo haría. ClassData es cuando desea escapar de la estática. Al hacerlo, puede reutilizar (es decir, anidar) los generadores más fácilmente.[MemberData("{static member}", MemberType = typeof(MyClass))]
para reemplazar elClassData
atributo.nameof
palabra clave en lugar de codificar el nombre de una propiedad (se rompe fácilmente pero en silencio).Para actualizar la respuesta de @ Quetzalcoatl: El atributo
[PropertyData]
ha sido reemplazado por el[MemberData]
cual toma como argumento el nombre de cadena de cualquier método estático, campo o propiedad que devuelve unIEnumerable<object[]>
. (Me parece particularmente agradable tener un método de iterador que realmente pueda calcular los casos de prueba uno a la vez, produciéndolos a medida que se calculan).Cada elemento en la secuencia devuelto por el enumerador es un
object[]
y cada matriz debe tener la misma longitud y esa longitud debe ser el número de argumentos para su caso de prueba (anotado con el atributo[MemberData]
y cada elemento debe tener el mismo tipo que el parámetro de método correspondiente . (O tal vez pueden ser tipos convertibles, no lo sé).(Consulte las notas de la versión de xUnit.net de marzo de 2014 y el parche real con código de ejemplo ).
fuente
Crear matrices de objetos anónimos no es la forma más fácil de construir los datos, así que usé este patrón en mi proyecto
Primero, defina algunas clases compartidas reutilizables
Ahora su prueba individual y sus datos de miembros son más fáciles de escribir y más limpios ...
La
Description
propiedad de la cadena es tirarse un hueso cuando uno de sus muchos casos de prueba fallafuente
Supongamos que tenemos una clase de automóvil compleja que tiene una clase de fabricante:
Vamos a completar y pasar la clase de Automóvil a una prueba de Teoría.
Así que cree una clase 'CarClassData' que devuelva una instancia de la clase Car como se muestra a continuación:
Es hora de crear un método de prueba (CarTest) y definir el coche como parámetro:
Buena suerte
fuente
Puedes probar de esta manera:
Cree otra clase para contener los datos de prueba:
fuente
Para mis necesidades, solo quería ejecutar una serie de 'usuarios de prueba' a través de algunas pruebas, pero [ClassData], etc., parecía excesivo para lo que necesitaba (porque la lista de elementos estaba adaptada a cada prueba).
Así que hice lo siguiente, con una matriz dentro de la prueba, indexada desde el exterior:
Esto logró mi objetivo, manteniendo clara la intención de la prueba. Solo necesita mantener los índices sincronizados, pero eso es todo.
Se ve bien en los resultados, es plegable y puede volver a ejecutar una instancia específica si obtiene un error:
fuente
MemberData
parece ser que no puede ver ni ejecutar la prueba con una entrada de prueba específica. Apesta.MemberData
si usaTheoryData
y opcionalmenteIXunitSerializable
. Más información y ejemplos aquí ... github.com/xunit/xunit/issues/429#issuecomment-108187109Así es como resolví tu problema, tuve el mismo escenario. Así que en línea con objetos personalizados y una cantidad diferente de objetos en cada ejecución.
Así que esta es mi prueba unitaria, observe el parámetro params . Esto permite enviar un número diferente de objeto. Y ahora mi clase DeviceTelemetryTestData :
Espero eso ayude !
fuente
Supongo que te equivocas aquí. Lo que
Theory
realmente significa el atributo xUnit : desea probar esta función enviando valores especiales / aleatorios como parámetros que recibe esta función bajo prueba. Eso significa que lo que se define como el siguiente atributo, tales como:InlineData
,PropertyData
,ClassData
, etc .. será la fuente de esos parámetros. Eso significa que debe construir el objeto fuente para proporcionar esos parámetros. En su caso, supongo que debería usar elClassData
objeto como fuente. Además, tenga en cuenta queClassData
hereda de:IEnumerable<>
- eso significa que cada vez que se utilizará otro conjunto de parámetros generados como parámetros entrantes para la función bajo prueba hasta queIEnumerable<>
produzca valores.Ejemplo aquí: Tom DuPont .NET
El ejemplo puede ser incorrecto: no usé xUnit durante mucho tiempo
fuente