views:

295

answers:

1

I am very new to TDD, ASP.NET MVC and LinqToSql. I am trying to write tests for my repository, which gets data from stored procedure using LinqToSql.

This is the repository method being tested:

public int GetResponseCount(int campaignId)
{
    var results = (new MyDBDataContext()).GetResponseCountById(campaignId);
    foreach (GetResponseCountByIdResult result in results)
    {
 return (result.ResponseCount != null) ? result.ResponseCount.Value : 0;
    }
    return 0;
}

This is the code in test:

var myDBDataContext = new Mock<MyDBDataContext>();
var result = new Mock<ISingleResult<GetResponseCountByIdResult>>().Object();
myDBDataContext.Setup(x => x.GetResponseCountById(It.IsAny<int>())).Returns(result).Verifiable();
...
...

There are 2 questions:

1) The sored procedure returns a single integer result. But I am having to loop through the response from LinqToSql to get to the value. Which is not ideal. Is there a better way to do it?

2) The code in test does not compile. The compiler says - Non-invocable member 'Moq.Mock<System.Data.Linq.ISingleResult<GetResponseCountByResult>>.Object' cannot be used like a method. How can I write test to verify that my repository method calls the right method in LinqToSql?

Many Thanks!

A: 

Hi Puneet,

I'd be inclined to encapsulate access to your DataContext so that you can intercept access to it (and thus mock the DC) for unit testing. this approach allows you to adapt your queries to get the single result when you need to:

public class MyDataAccess{
  public X GetMyX(){
    using (var ctx = new DataContext()){
      return (from x in ctx.TheXs where... select x).FirstOrDefault();
    }
  }
}

That way, you can mock the data context, providing your own results inside of your unit tests, and also adapt the query to get the first answer from your sequence when you are confident that there is only one result.

Best Wishes,

Andrew

Andrew Matthews