Problem when testing LINQ To SQL Classes objects

I am writing a small web shop application using ASP.NET MVC Framework. As a part of this project I also write unit test and integration tests. I am using LINQ To SQL Classes as a mapping solution in my project. I found one misleading behaviour of LINQ To SQL Classes when writing integration tests.

Look at these two test. They are same test but with little differences. Note: ProductRepository uses Linq To SQL DataContext internally. All changes are flushed to database after inserting, deleting and updating products. GetProduct() creates new product and initializes all properties. The test should fail with last Assert shown in both versions.

Passes


public void Should_insert_new_product()
{
   
var
product = GetProduct();

   
var repository = new ProductRepository
();
    repository.Save(product);

   
Assert
.AreNotEqual(0, product.Id);

   
var
id = product.Id;
   
var savedProduct = (Product
)repository.GetById(id);

   
//...
    Assert
.AreEqual(_listIcon, savedProduct.ListIcon);
   
//...
}

Fails


public void Should_insert_new_product()
{
   
var
product = GetProduct();

   
var repository = new ProductRepository
();
    repository.Save(product);

   
Assert
.AreNotEqual(0, product.Id);

   
var
id = product.Id;

    repository.Dispose();
    repository =
new ProductRepository
();

   
var savedProduct = (Product
)repository.GetById(id);

   
//...
    Assert
.AreEqual(_listIcon, savedProduct.ListIcon);
   
//...
}

Why should this test fail? The point simple – Product.ListIcon is currently just a property that is not bound to database. As it turns out then LINQ To SQL caches objects somewhere and is able to return object with the same ID from somewhere. When disposing repository then repository also disposes DataContext and everything gets cleaned up.

It turns out that for testing we should also dispose DataContext after each operation so we don’t face caching problems when we want to see if database operations work as expected.


Leave a Reply

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