Escribiendo una Aplicación usando TDD (Part 5) Agregando Vistas

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

This entry was posted in 10549, 11699, 13362, 1389, 3463, 5374. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>