2010-10-27 11 views
11

considerar:¿Cómo escribir una prueba unitaria para "T debe ser un tipo de referencia"?

class MyClass<T> where T : class 
{ 
} 

En ese caso, la cláusula where está haciendo cumplir una especificación que MyClass sólo es un genérico de un tipo de referencia.

Idealmente, debería tener una prueba de unidad que pruebe esta especificación. Sin embargo, esta prueba unitaria, obviamente, no va a funcionar, pero explica lo que estoy tratando de lograr:

[Test] 
[DoesNotCompile()] 
public void T_must_be_a_reference_type() 
{ 
    var test = new MyClass<int>(); 
} 

¿Qué puedo hacer yo para probar una especificación que ha implementado al no permitir que el código para compilar?

EDITAR:

Más información: Ok, así que mi razonamiento para hacer esto (jaja) es que he estado siguiendo una metodología TDD, en la que no se puede escribir cualquier código a menos que tenga una prueba de falla de la unidad. Digamos que usted ha tenido este:

class MyClass<T> { } 

¿Qué prueba se puede escribir que fallarían a menos T eran una clase? Algo como default(T) == null?

hacer otras modificaciones:

Así que después de un "análisis de la causa raíz" en esto, el problema es que me baso en default(T) siendo null en un consumidor de esta clase, de manera implícita. Pude refactorizar ese código de consumidor en otra clase y especificar allí una restricción de tipo genérico (restringiéndolo a class) que efectivamente hace que ese código no se compile si alguien elimina la restricción en la clase de la que estoy hablando anteriormente.

+3

¿Por qué no está probando que la clase se llama 'MyClass'? – SLaks

+0

@SLaks: técnicamente var test = new MyClass (); lo probaría, ¿no? –

+0

Creo que @SLaks estaba usando el sarcasmo para demostrar que no es necesario probar el compilador ... ese es el trabajo de Microsoft. – TheCloudlessSky

Respuesta

25

¿Por qué necesitaría una prueba unitaria para esto? Cómo se escribe una prueba unitaria para un procedimiento tal como

public void Foo(string x) 

para comprobar que sólo puede tener cadenas, y no enteros? Si no, ¿qué ves como la diferencia?

EDITAR: Para ser un poco menos caprichoso: en este caso, la especificación es validada por la declaración . Las pruebas generalmente deben probar el comportamiento . Esa es una de las cosas que me gustan de los contratos de código: no siento la necesidad de probar los contratos a menos que expresen algo complicado, en cuyo caso es esa complejidad la que probaría, no el bit de los "contratos se aplican" .

EDIT: Para responder a la pregunta de edición:

¿Qué prueba se puede escribir que fallarían a menos T eran una clase?

Usted podría escribir algo como:

Type definition = typeof(MyClass<>); 
Assert.Throws<ArgumentException>(() => definition.MakeGenericType(typeof(int))); 

Sin embargo, esto parece ir en contra del propósito real de la prueba ...

+0

Bueno, estoy tratando de hacer que mis pruebas unitarias incluyan todas las especificaciones para la unidad bajo prueba. –

+0

@Jon Gracioso, pensamos en exactamente el mismo ejemplo –

+2

@Scott Whitlock - Pero simplemente que el código se compila ** es ** su prueba. –

9

No debe comprobar si el compilador hace su trabajo. Si especifica esto en el código, esto es suficiente. Desde el punto de vista de código, esto es más o menos lo mismo que esto:

[Test] 
public void Test_whether_add_works() 
{ 
    int i = 1 + 2; 

    Assert.AreEqual(3, i); 
} 
+4

'[Test] public void Running1984() {Assert.AreEqual (5, 2 + 2); } ' –

+0

Hihi, Radiohead. –

2

¿Estás escribiendo una prueba de unidad correcta? Parece que vas a probar el compilador C# pero no tu código.

3

Esta es una gran pregunta! Estoy tan de acuerdo con su enfoque impulsado por la prueba. Con lo que estás luchando es en realidad el choque de dos paradigmas. El viejo paradigma de que los programas deben ser probados correctamente usando las matemáticas sin ejecutarlos (un legado de la ascendencia de nuestra profesión en matemáticas) y el nuevo paradigma que programó deberían ser probados al ejecutar ejemplos de casos de uso, es decir, pruebas. Entonces, lo que está a punto de intentar es aplicar la práctica del nuevo paradigma sobre un artefacto del antiguo paradigma, que por supuesto no funcionará realmente ...

Más sobre la dicotomía de tipos y pruebas, consulte este excelente artículo por Chris Smith, http://web.archive.org/web/20080822101209/http://www.pphsg.org/cdsmith/types.html

Cuestiones relacionadas