¿Por qué escribirías pruebas unitarias para controladores?

22

Para mí, esta es una prueba de unidad totalmente irrelevante y no entiendo por qué alguien pasaría tiempo escribiéndola, ya que hay muy poco valor para obtenerla. Lo sabría perfectamente si este controlador devolviera el tipo deseado ejecutando el método en un navegador. Realmente, ¿crees que se necesita una prueba para esto y por qué?

public class ConstituencyControllerTests
{
    private ConstituencyController _constituencyController;
    private Mock<IConstituencyService> _IConstituencyServiceMock;

    public ConstituencyControllerTests() {
        _IConstituencyServiceMock = new Mock<IConstituencyService>();
    }

    [Test]
    public async Task I_Check_For_Return_Type_And_Result() {
        _constituencyController = new ConstituencyController( _IConstituencyServiceMock.Object );

        var result = await _constituencyController.Get();
        var content = ( (dynamic)result ).Content;

        Assert.IsEmpty( content );
        Assert.IsInstanceOf( typeof( System.Web.Http.Results.OkNegotiatedContentResult<IEnumerable<ListOfConstituencies>> ), result );
        _IConstituencyServiceMock.Verify( x => x.ListOfConstituencies(), Times.Once() );
    }
}
glaseados
fuente
77
No estés de acuerdo con eso @gnat. No se trata necesariamente de construcciones de lenguaje, sino del tipo de resultado devuelto por un controlador. Si bien puede reducirse a una especie de lo mismo cuando no tiene una jerarquía de herencia, se convierte en una bestia completamente diferente cuando el controlador espera que se devuelvan los antepasados, el controlador devuelve la Persona y ahora se cambia la Persona para descender no del Ancestro, sino PeopleAncestor ... También responde por qué probar un método de este tipo puede ser una buena idea ...;) Las pruebas unitarias están destinadas a detectar situaciones en las que un cambio en una cosa c / rompería otra cosa.
Marjan Venema
Tiendo a estar de acuerdo, normalmente no paso mucho tiempo en la unidad probando los puntos de entrada de la aplicación. Es como la unidad que prueba un método principal de una aplicación de consola. solo tiene muy poco sentido para mí.
Mvision

Respuestas:

29

El punto clave está aquí:

Lo sabría perfectamente si este controlador devolviera el tipo deseado ejecutando el método en un navegador

La prueba unitaria se trata de la automatización de pruebas de no regresión de unidades simples de código, no de que usted mismo se vea. No desea hacer usted mismo siempre pruebas unitarias en su aplicación.

EDITAR: Agregar comentario @anotherdave:

Se trata de la facilidad de escalado. Probar un controlador en un navegador puede estar bien; ¿Qué pasa con 10, 20, 50 controladores? Escribirás la prueba una vez; Es posible que deba actualizarlo cuando cambie el controlador, que está sobrecargado. Pero, ¿con qué frecuencia se implementa? Seguramente una comprobación manual cada vez que hay mucho más gastos generales que la prueba

Como alternativa a la respuesta de @ Vladislav , la unidad que prueba absolutamente todo puede ser una exageración, y realmente indeseable. Si necesita algo más liviano, puede hacer pruebas de no regresión de mayor nivel utilizando Selenium. Seguramente obtendrá menos cobertura que las pruebas unitarias, pero puede obtener una cobertura razonable que cuesta mucho menos tiempo haciendo pruebas unitarias y es más flexible.

Es decir, si realiza una prueba unitaria de todo, debe actualizar una o más pruebas cada vez que modifique un elemento simple.

Walfrat
fuente
44
También para agregar re: I would know perfectly well if this controller returned the wanted type by executing the method in a browser.- se trata de la facilidad de escalado. Probar un controlador en un navegador puede estar bien; ¿Qué pasa con 10, 20, 50 controladores? Escribirás la prueba una vez; Es posible que deba actualizarlo cuando cambie el controlador, que está sobrecargado. Pero, ¿con qué frecuencia se implementa ? Sin duda, una comprobación manual cada vez que hay mucho más gastos generales que la prueba.
otrada el
"Las pruebas unitarias son sobre automatización" - Correcto, pero también lo son las pruebas de integración (Selenium / Webdriver / etc.). No creo que sea necesariamente tan simple que las pruebas unitarias sean más rápidas de implementar que las pruebas de integración. Mucho depende del enfoque, sin embargo, si obtener una prueba de unidad efectiva requiere burlarse de una docena de servicios y llamadas diferentes realizadas en cada uno, una prueba de integración puede ser más rápida de implementar y más simple de mantener (aunque generalmente es mucho más lenta de ejecutar, sí) . El punto es que mucho depende del contexto y la complejidad del código bajo prueba.
Aroth
Comentario de @anotherdave agregado
Walfrat
@aroth, mi punto era lo contrario, la prueba de unidad completa de un código es algo que lleva mucho tiempo y hace que el código sea muy difícil de cambiar sin tener que cambiar alguna prueba de unidad. La prueba de integración es más ligera. Por supuesto, desearía que la prueba de unidad sea algo muy complejo, pero no es porque haya probado esa parte de la unidad, sino que tiene que probar todo de forma unitaria. Una vez más vemos personas buscando la bala de plata donde él no existe.
Walfrat
24

¿Por qué escribirías pruebas unitarias para controladores?

Porque sin conocer el contexto no puedes decir con certeza si necesitas probar esto o aquello. Aquí hay algunas razones por las que es posible que desee probar los controladores:

  • El controlador puede contener una lógica de cableado de servicio compleja, que es propensa a errores. Los servicios en sí pueden funcionar bien, es el resultado que desea probar y, por alguna razón, consideró no introducir la capa de orquestación en su aplicación
  • sus controladores contienen TODA la lógica de negocios de la aplicación y los controladores son en realidad todo lo que PUEDE probar (por favor, no pretenda que toda su vida trabajó con bases de códigos ideales, existen tales bases de códigos, créanme)
  • su equipo está formado por el 99% de genios y el 1% de las personas promedio y desea mantener ese 1% fuera de los errores en su salario
Vladislav Rastrusny
fuente
2
Yo agregaría: "No se puede prever quién en el futuro se va a deshacer del proyecto, y las pruebas son parte del código auto documentado"
Laiv
44
Para el punto medio, un proyecto que se creó sin tener en cuenta las pruebas puede no ser comprobable de otra manera que no sea una prueba de controlador sin simulacros. Trabajo con un equipo de C # que tiene exactamente ese proyecto a su cargo, por lo que están escribiendo pruebas de controlador hasta que puedan agregar la estructura necesaria (interfaces, etc.) para poder realizar pruebas más precisas.
Wayne Conrad
1

Estoy completamente de acuerdo con el OP.

Una prueba unitaria para un controlador no tiene sentido. Usted prueba sus controladores implícitamente mediante pruebas de regresión (usando Selenium, por ejemplo).

Debe TDD todos los componentes / objetos que usa el controlador y mantener los controladores lo más delgados posible. Entonces todo se prueba adecuadamente en la unidad. De lo que quiere estar seguro es de que todo funciona bien cuando se realizan solicitudes web. Eso es prueba de regresión.

winkbrace
fuente
Tal vez sí, pero esa no es una respuesta a la pregunta. De hecho, es un argumento en contra del uso de pruebas unitarias aquí.
JᴀʏMᴇᴇ
Creo que respondí la pregunta "¿Crees que se necesita una prueba para esto y por qué?"
winkbrace
Sí, creo que @winkbrace y yo compartimos los mismos pensamientos sobre esto. Pero también creo que es una discusión acerca de lo que debe probar unitaria y no. Creo que la gente prueba demasiado y las cosas "equivocadas". en mi ejemplo, probar el controlador da muy poco valor ya que es muy delgado y es de esperar que tenga pruebas que rodean los servicios. Todas las respuestas aquí son significativas y tienen buenos puntos, pero en realidad no es posible marcar una como respuesta correcta.
glaseados
La lógica del controlador se puede probar usando pruebas de integración automatizadas, separadas y distintas de las pruebas unitarias para componentes individuales.
KevBurnsJr
-1: Una prueba unitaria para un controlador podría no tener sentido. Los controladores tratan sobre la transformación, pero a veces la transformación en sí misma es compleja y un desarrollador puede querer tenerla cubierta. También creo que las pruebas unitarias 1) se tratan en última instancia de validar una implementación, no necesariamente de validar el comportamiento de alto nivel, y 2) se supone que son muy rápidas . Ambas cualidades hacen que las pruebas unitarias sean mucho más útiles durante el tiempo de implementación; en otras palabras, en última instancia, son una herramienta para desarrolladores y, por cierto, una forma de validar la calidad del producto.
rsenna