Anterior Post
Próximo Post
Ahora ya tengo algunos tests y en verde. Voy a agregar algunas vistas MVC en este paso de hoy. Pueden bajar el código desde mi AjCodeKatas Google Project, en trunk/AppTdd/Step04. Así que este post tiene pocos nuevos tests: muestra que podemos agregar interfaz de usuario DESPUES de los tests, y (para destacar) SIN TENER una base de datos aún, ni siquiera una capa de servicios (“service layer”).
Primero, agregué una master page Site.master y un estilo style.css (que tomé de otro proyecto ASP.NET MVC 2)
Agregué un nuevo controlador Home:
Y usando el menú de contexto sobre el método Index agregué una vista asociada al método:
Modifiqué el código de la master page para tener una nueva opción en el menú:
Entonces, agregué una vista, esta vez asociada al método Index del controlador Subject:
Seleccioné a “List” como “Vien Content”, y a “Subject” como el tipo a usar como base del modelo.
Pero el método del controlador es:
public ActionResult Index()
{
return View(subjects);
}
Usa una lista de temas (“subjects”) que ha sido inyectada hasta ahora en un constructor por los tests:
public SubjectController(IList<Subject> subjects)
{
this.subjects = subjects;
}
Pero esperen! Esa lista es inyectada por los tests. Ahora, necesito que esté disponible en el proceso normal de un controlador. Así que agregué un constructor sin parámetros:
public SubjectController()
: this(Domain.Instance.Subjects)
{
}
El Domain.Instance es un dominio en memoria:
public class Domain
{
private static Domain instance = new Domain();
private Domain()
{
this.Subjects = new List<Subject>()
{
new Subject() { Id = 1, Name = "Mathematics" },
new Subject() { Id = 2, Name = "Physics" },
new Subject() { Id = 3, Name = "Biology" },
new Subject() { Id = 4, Name = "Literature" }
};
}
public static Domain Instance { get { return instance; } }
public IList<Subject> Subjects { get; set; }
}
Ahora sí el controlador de Subject puede manejar el método Index. Cambio enlaces en la vista que me agregó el wizard. Los cambio de:
a que usen la propiedad Id como clave primaria:
Este es el resultado:
Creé entonces otras vistas, para los otros métodos del controlador Subject. Seguí usando el wizard de Visual Studio “Add View … “:
Me encontré que me faltaban algunas acciones. Escribí una nueva:
public ActionResult Edit(int id)
{
var model = this.subjects.Where(s => s.Id == id).FirstOrDefault();
return View(model);
}
con tests! ;-)
[TestMethod]
public void GetSubjectForEdit()
{
IList<Subject> subjects = GetSubjects();
SubjectController controller = new SubjectController(subjects);
ActionResult result = controller.Edit(1);
Assert.IsNotNull(result);
Assert.IsInstanceOfType(result, typeof(ViewResult));
ViewResult viewResult = (ViewResult)result;
Assert.IsInstanceOfType(viewResult.ViewData.Model, typeof(Subject));
Subject model = (Subject)viewResult.ViewData.Model;
Assert.AreEqual(1, model.Id);
Assert.AreEqual("Mathematics", model.Name);
}
Curiosamente, detecté un test “malo”. Yo había escrito en test AddSubject:
Assert.IsTrue(subjects.Any(s => s.Name == "Chemistry"));
Assert.AreEqual(4, subject.Id);
Pero el nuevo Id debería dar 5 (mi lista usada en los tests tiene 4 temas predefinidos (“subjects”)):
Assert.IsTrue(subjects.Any(s => s.Name == "Chemistry"));
Assert.AreEqual(5, subject.Id);
Arreglé el código y la acción del controler, ejecuté la aplicación web, y voila! Todo funcionó.
Puntos principales:
- Estoy usando un dominio en memoria.
- Las vistas se ejecutan sobre las acciones YA probadas con tests
No hay capa lógica de servicios ni persistencia, aún. Vean que no son necesarias al principio. Voy a agregar una “service layer” como gran refactor. Otros próximos pasos: agregar más clases al dominio (libros en clase Book), escribir esa capa de servicio usando tests, “enchufarla” en los controladores. Y en algún momento agregar persistencia.
Pueden leer posts interesantes sobre TDD sin una base de datos (o agregándola después) escritos por @RonJeffries:
But We Need a Database … Don’t We? | xProgramming.com
See? We Don’t Need a Database … Yet | xProgramming.com
Nos leemos!
Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez