Estoy tratando de comprender cuál es la idea detrás de TDD y cómo se supone que un equipo debe trabajar con ella. Tengo el siguiente caso de prueba con NUnit + Moq (solo escribiendo de memoria, no se garantiza que el ejemplo se compila, pero debería ser explicativo):
[Test]
public void WhenUserLogsCorrectlyIsRedirectedToLoginCorrectView() {
Mock<IUserDatabaseRepository> repoMock = new Mock<IUserDatabaseRepository>();
repoMock.Setup(m => m.GetUser(It.IsAny())).Returns(new User { Name = "Peter" });
Mock<ILoginHelper> loginHelperMock = new Mock<ILoginHelper>();
loginHelperMock.Setup(m => m.Login(It.IsAny(), It.IsAny())).Returns(true);
Mock<IViewModelFactory> factoryMock = new Mock<IViewModelFactory>();
factoryMock.Setup(m => m.CreateViewModel()).Returns(new LoginViewModel());
AccountController controller = new AccountController(repoMock.Object, loginHelperMock.Object, factoryMock.Object)
var result = controller.Index(username : "Peter", password: "whatever");
Assert.AreEqual(result.Model.Username, "Peter");
}
AccountController tiene 3 dependencias de las cuales me burlo que, cuando se orquesta dentro del controlador, me permite verificar si un inicio de sesión fue correcto o no.
Lo que me hace pensar es que ... si en teoría TDD tiene que escribir primero su conjunto de pruebas y construir su código a partir de él, ¿cómo se supone que debo saber de antemano que para realizar mi operación tendré que usar esas tres dependencias y que la operación llamará ciertas operaciones? Es como si necesitara conocer las entrañas del sujeto bajo prueba antes de incluso implementarlo para burlar las dependencias y aislar la clase, creando algún tipo de prueba de escritura - código de escritura - modificar la prueba si es necesario.
Naturalmente, sin ningún conocimiento de las entrañas de mi código y solo expresando la prueba, podría expresarlo como si solo necesitara el ILoginHelper y supongo "mágicamente" antes de escribir el código que devolverá al usuario un inicio de sesión exitoso (y finalmente darse cuenta de que el marco subyacente no funciona de esa manera, por ejemplo, devolver solo una ID en lugar del objeto completo).
¿Estoy entendiendo TDD de manera incorrecta? ¿Cuál es una práctica típica de TDD en un caso complejo?
Gracias