Su experiencia es muy similar a la mía está comenzando. Mientras me venden en TDD y no haría las cosas de manera diferente, ciertamente entiendo tu confusión. Es importante recordar que TDD es una filosofía de diseño. Dicho eso, creo que puedo ayudar a aclarar algunas de tus frustraciones.
Comience pensando en lo que está tratando de lograr, no en un nivel de prueba individual, pero qué es lo que está tratando de hacer. Si su tarea (historia del usuario) implica tomar algunas credenciales e intentar autenticar al usuario actual en función de esas credenciales, entonces comience desde allí y siga su camino hacia abajo. Usted parece estar yendo en esta dirección, solamente se queda pegada sobre los próximos pasos
Cuando se trabaja en una prueba individual, pensar en ella en términos de expected behavior en lugar de sólo la verificación de algunas entradas y salidas. Piense en sí mismo como si usara este componente, y simplemente escriba una línea de código de la forma en que desea que se escriba. Deje que esta parte ayude a conducir la interfaz/contrato de su servicio. Tienes que hacerte la pregunta: "Si tuviera que llamar a este método, ¿cómo iba a saber si funcionaba? ¿Qué esperaría que hiciera?" Esto determinará qué tipo de afirmaciones debe hacer.
Determine cuáles son sus dependencias externas, y utilize abstractions instead (principio de inversión de dependencia). Si estas dependencias son algo que le interese como parte de su verificación de comportamiento, entonces use dependency injection para poder usar un mock en su prueba.
Siempre, siempre, siempre siga este orden [Escriba su prueba, mire si falla, código para pasar, refactorizador]. ¡¡¡APRENDA DE MIS ERRORES !!! Créanme, esto no es negociable. De lo contrario, es probable que culpe a sus problemas con TDD cuando no se está empleando correctamente.
Ok, por lo que poner todo esto junto con su ejemplo, y algunos muy bien proporcionado test cases from lance, podríamos hacer algo como esto:
[Test]
public void ShouldAuthenticateValidUser()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsTrue(service.DoLogin("Name", "Password"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
[Test]
public void ShouldNotAuthenticateUserWithInvalidPassword()
{
IMyMockDa mockDa = new MockDataAccess();
var service = new AuthenticationService(mockDa);
mockDa.AddUser("Name", "Password");
Assert.IsFalse(service.DoLogin("Name", "BadPassword"));
//Ensure data access layer was used
Assert.IsTrue(mockDa.GetUserFromDBWasCalled);
}
Ok, así que hay mucho que hacer allí, y quizás mucho para investigar. Sin embargo, puede comenzar a ver cómo es posible realizar pruebas exhaustivas utilizando un mejor diseño. En los ejemplos anteriores, es importante tener en cuenta que el objeto simulado se rueda de forma personalizada, pero no tiene que pasar por todo este dolor. Hay muchos Frameworks burlones por ahí. Por ejemplo, utilizando RhinoMocks, la prueba se vería así:
[Test]
public void ShouldAuthenticateValidUser()
{
var mockRepo = new MockRepository();
var mockDa = mockRepo.DynamicMock<IMyMockDa>();
var service = new AuthenticationService(mockDa);
using(mockRepo.Record())
{
//I realize this is a terrible method and should not exist if you
// care about security, but for demonstration purposes...
Expect.Call(mockDa.GetPassword("User")).Return("Password");
}
using(mockRepo.Playback())
{
Assert.IsTrue(service.DoLogin("User", "Password"));
}
}
acostumbrarse a hacer las cosas de manera manual del primero para que entienda los conceptos, y luego pasar a la utilización de un marco. ¡Uf! Mucha información, pero como puede ver, TDD es una filosofía de diseño completa. Sin embargo, dará como resultado un código más limpio, un mejor diseño y menos errores.
¡Muchas gracias por tomarse el tiempo de escribir esto! Realmente lo aprecio. Dijiste muchas cosas buenas y probablemente me tome un tiempo entender todo. Tienes razón en que tengo que acostumbrarme a pensar de manera diferente cuando hago TDD. Espero que mi confusión pase algún día, pero eso solo llevará tiempo. ¡Gracias de nuevo! – CalebHC
Pasó mucho tiempo antes de que tuviera ese momento "Ah Ha", pero ahora estoy totalmente convertido. Te animo a que compruebes otra publicación SO que hice sobre TDD: http://stackoverflow.com/questions/106800/unit-testing-guidelines/106813#106813 – Josh
La representación incompleta que viste es un error conocido con respuestas antiguas - Puedes arreglar esto para cualquier respuesta (no solo la tuya) enviando cualquier edición, lo que obliga a volver a generar la respuesta. Esto también explica por qué se ve bien cuando aparece por primera vez el editor. He retocado el formato aquí, pero también puedes enviar una edición de stub y deshacerlo y aún obligará a la respuesta a volver a generar. – BoltClock