How to best create a test DB when doing TDD? How to best create a test DB when doing TDD? asp.net asp.net

How to best create a test DB when doing TDD?


Assuming you're using the Repository pattern from Rob Conery's MVC Store Front:

http://blog.wekeroad.com/mvc-storefront/mvc-storefront-part-1/

I followed Rob Conery's tutorial but ran into the same want as you. Best thing to do is move the Mock Repositories you've created into a seperate project called Mocks then you can swap them out pretty easily with the real ones when you instantiate your service. If your feeling adventurous you could create a factory that takes a value from the config file to instantiate either a mock or a real repository,

e.g.

public static ICatalogRepository GetCatalogRepository(bool useMock){     if(useMock)          return new FakeCatalogRepository();     else          return new SqlCatalogRepository();}

or use a dependency injection framework :)

container.Resolve<ICatalogRepository>();

Good luck!

EDIT: In response to your comments, sounds like you want to use a list and LINQ to emulate a db's operations e.g. GetProducts, StoreProduct. I've done this before. Here's an example:

public class Product{     public int Identity { get; set; }     public string Name { get; set; }     public string Description { get; set; }     //etc}public class FakeCatalogRepository(){     private List<Product> _fakes;     public FakeCatalogCatalogRepository()     {          _fakes = new List<Product>();          //Set up some initial fake data          for(int i=0; i < 5; i++)          {              Product p = new Product              {                 Identity = i,                 Name = "product"+i,                 Description = "description of product"+i              };              _fakes.Add(p);          }     }     public void StoreProduct(Product p)     {         //Emulate insert/update functionality         _fakes.Add(p);     }     public Product GetProductByIdentity(int id)     {          //emulate "SELECT * FROM products WHERE id = 1234          var aProduct = (from p in _fakes.AsQueryable()                         where p.Identity = id                         select p).SingleOrDefault();          return aProduct;     }}

Does that make a bit more sense?


Boring or not, I think you're on the right track. I assume you're creating a fakeRepository that is a concrete implementation of your IRepository which in turn is injected into your service layer. This is nice because at some point in the future when you're happy with the shape of your entities and the behavior of your services, controllers, and views, you can then test drive your real Repositories that will use the database to persist those entities. Of course the nature of those tests will be integration tests, but just as important if not more so.

One thing that may be less boring for you when the time comes to create your real repositories is if you use nHibernate for your persistence you will be able let nhibernate generate your database after you create the nhibernate maps for your entities, assuming you don't have to use a legacy schema.

For instance, I have the following method that is called by my SetUpFixture to generate my db schema:

public class SchemaBuilder{   public static void ExportSchema()    {        Configuration configuration = new Configuration();        configuration.Configure();        new SchemaExport(configuration).Create(true, true);    }}

and my SetUpFixture is as follows:

[SetUpFixture]public class SetUpFixture{    [SetUp]    public void SetUp()    {        SchemaBuilder.ExportSchema();        DataLoader.LoadData();    }}

where DataLoader is responsible for creating all of my seed data and test data using the real respoitory.

This probably doesn't answer your questions but I hope it serves to reassure you in your approach.

Greg


Although I'm not using Asp.Net or the MVC framework I do have the need to test services without hitting the database. Your question triggered the writing up of a short (ok, maybe not so short) summary of how I do it. Not claiming it's the best or anything, but it works for us. We access data through a repository and when required we plug in an in-memory repository as explained in the post.

http://blogs.microsoft.co.il/blogs/kim/archive/2008/11/14/testable-data-access-with-the-repository-pattern.aspx