ASP.net MVC RC1 – Removing Code Behind files

With ASP.net MVC, one thing I always wondered is why we still had to have the code behind files. Looking at the FubuMVC samples, everything looks much cleaner without the additional files – with RC1, code-behind files are no longer required!

However, if your upgrading from beta, you will need to change your ASPX pages. In this post, I will cover the steps I went through to remove these files.

During beta, my solution looked looked like this:

image

In my code behind, I have a mixture of strongly typed ViewPage objects and the standard ViewPage. As a result, in my ASPX page, I had a CodeBehind file and a Inherits tag.

image

With RC1, I can remove the CodeBehind tag and replace the Inherits to System.Web.MVC.ViewPage directly.

image

I can now delete Index.aspx.cs and Index.aspx.designer.cs leaving me with just the Index.aspx file.

If my ViewPage was strongly typed with a model, the the Inherits tag would include this, just like with the code behind model:

image

For ASP.net MVC User Controls, instead of ViewPage you use ViewUserControl:

image

Similarly with Master Pages:

image

After changing all my views, controls and master pages, my solution looks like this:

image

This makes me happy.

UPDATE: Parser Error Message: Could not load type ‘System.Web.Mvc.ViewPage‘.

Ok – I made a little mistake. When I hit my ViewPage, I received a Parser error message. If I had paid more attention to the release notes, I would have noticed I needed to copy an additional block of xml into my web.config.

     pageParserFilterType=”System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″
     pageBaseType=”System.Web.Mvc.ViewPage, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″
     userControlBaseType=”System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35″>
      
           
      

Technorati Tags:

Upgrading a project from ASP.net MVC Beta to ASP.net MVC RC1

As I’m sure you are well aware, the ASP.net team have released ASP.net MVC RC1 tonight.  Eager to find out how much additional work I had, I downloaded and upgraded my solution – I was pleasantly surprised.

All I had to do was:

  • Uninstall beta bits
  • Install RC1 bits
  • Update project references for System.Web.Abstractions.dll, System.Web.Mvc.dll and System.Web.Routing.dll
  • Build
  • Test
  • Done!

Following my own advice, I commit the updated installer and assemblies into source control. Everything appears to be working, but I guess your mileage may vary.

Technorati Tags:

Model View Controller (MVC) Pattern – The core concept

Everyone is talking about the Model View Controller, or MVC, pattern.  In this post I’m going to focus on the pattern itself and the concepts around it for anyone who hasn’t come across this pattern before, or who just wants a simply refresher.  The pattern itself has been around for many years, way back to the days of smalltalk, however has become popular and came into the limelight over the last number of years with different web frameworks ‘encouraging’ the use of the pattern.

The pattern describes how to separate your business logic (what the application should do) and the UI (how it looks).  There are huge advantages to this:

  • It promotes code reuse as code isn’t isolated in a button’s click action
  • Maintenance of the application is easier as changing one side of the system doesn’t have the additional noise of the other side.  When changing your business rules, you don’t have to interact with the code which displays everything on screen.
  • UI is difficult to test, if you remove the UI then testing becomes easier.  As everything is more separated and has cleaner interfaces, it becomes easier to write your automated test cases.
  • Having everything separated means different parts can be interchanged/replaced easier.

What the pattern is really attempting to achieve is a separate of concerns with the different parts of the system just dealing with their own responsibilities.

However, most applications do not follow this pattern and mix up all the layers together. Microsoft samples are quite bad for doing this where they have SQL connections and queries in a button click event. However, the current architecture of WebForms doesn’t fit well with the MVC approach (of course part from the new MVC framework).  The reason it doesn’t fit well is because you can have SqlDataSource and DataGrids on the webpage which contain sql statements and database connections resulting in just a single UI layer.  This is fine for Rapid Application Development (RAD) and very quick sites, but for enterprise level applications this approach is not maintainable.

By following the MVC pattern, your application will be architected in a very different manner. There are three main components to the system:

  • Model – Object representing data or state within the system.  This could be an ‘Order’ object which represents a row in the database or maybe an arm on a robot.
  • Controller – This handles the application flow.  This handles which views should be rendered, which data to display and any validation which is required.  This is most definitely not a God Class and its important not to put everything into a single controller. 
  • View – The single role of a view is to correctly display the data.  It takes the model given to it from the controller and outputs it in the correct way.

With an application separated in this way, we can replace different parts of the application without affecting too much of the application.  How we actually implement the pattern is dependent on the platform building upon. It is possible to implement this pattern in any system, however the new ASP.net MVC Framework will definitely help in managing the interaction.

Technorati Tags: ,

‘System.Web.Mvc.Controller’ is defined in an assembly that is not referenced

While I was playing around with the Mvc framework, I received this error message:

The type ‘System.Web.Mvc.Controller’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘System.Web.Extensions, Version=3.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’. 

What this simply means, is that I forgot to reference the System.Web.Extensions within my code,  in this case it was by test harness/project.

image image

However, when I looked in the .Net reference table, I couldn’t see the 3.6.0.0 assembly listed.  I went into the GAC (C:WindowsAssembly) and there it was listed but it wouldn’t let me reference the assembly. Finally, I went to C:Program FilesReference AssembliesMicrosoftFrameworkASP.NET 3.5 Extensions and added the reference from there.

Remember, if your creating your own test project with NUnit or MbUnit then you will need to reference System.Web.Extensions within that project as well.

Technorati Tags: ,

First play with ASP.net MVC

(UPDATE: Cheers LiveWriter – Post to weblog as draft causes it to publish. Sorry for any mistakes in first attempt, this I have fixed them all)
In this post, I’m going to discuss my experience while having a play with the ASP.net MVC framework. Over the next series of posts, I’ll go back over some of the items discussed and deep dive into them to provide more information. Tonight, I just wanted to get my initial thoughts out while it was still hot.

The installation and download was quite simply and didn’t have any problems with the install.

image

However, this brings me onto problem number one. The assemblies are required to be installed into the GAC! This is impossible with Shared Hosters (unless some hosters out there are willing to install CTPs on production servers). This means I can’t deploy samples / test sites until its RTM! Guess I’ll just have to publish the code. If anyone knows any hosters offering ASP.net MVC hosting, please leave a comment.

Once installed, you will have a number of new templates within your Visual Studio new project dialog.

image

There are two main projects, one is ASP.NET MVC Web Application and Test with the other being ASP.NET MVC Web Application. The first project includes the second project type (just the web app) which will setup the correct folder directory and give you the base template to fill in. It will also create a MSTest project to start writing your unit tests.

After creating the projects. the layout is below.

image

A few things I wanted to point out. The content directory has the stylesheet for the site, this is where images etc will go. The controllers folder will contain the controller classes which will have all the methods for the application. The models will contain any objects related to storing your data. Views will contain the ASPX pages (and master pages).

The other thing you notice is that there is a default.aspx in the root directory. If you open the file, it has the following message.

This makes sense, bit of a hack but never mind. If we load the website, then it will look like below.

image

Great, now lets start having a play. First thing I want to do, add a text box. Hit F5 and I got an exception.

System.Web.HttpException was unhandled by user code
Message=”Control ‘ctl00_MainContentPlaceHolder_TextBox1’ of type ‘TextBox’ must be placed inside a form tag with runat=server.”
Source=”System.Web”
ErrorCode=-2147467259

As I added the control in code view, it didn’t automatically add a form tag for me. Easily fixed.

Hit F5 again and I got another exception.

System.NullReferenceException was unhandled by user code
Message=”Object reference not set to an instance of an object.”
Source=”App_Web_t1migfpo”

This was because Visual Studio had pointed me to the full path for the ASP.net page (WebForms style – http://localhost:64701/Views/Home/Index.aspx). However, with MVC this doesn’t work as you navigate the site via defined routes, if I go directly to the root of the website and it works fine.

Now, the main thing I want to look at first is how to test the controller.

Testing the controller

The first task I wanted to do was delete the test project and re-created it with a C# class library referencing the MbUnit.Framework assembly.

After I had it correctly building, I wanted to test the Index action on the test controller. This is the first method called in our code and deals with what should happen when the homepage / index is visited. At the moment, all it does it tell the Index page to render.

Just to get an idea, I just wrote the simple test below to see what happened (and changed) when Index() was called.

[Test]
public void IndexTest()
{
HomeController controller = new HomeController();
controller.Index();
}

However, this throw an exception.

[failure] HomeControllerTests.IndexTest
TestCase ‘HomeControllerTests.IndexTest’ failed: Object reference not set to an instance of an object.
System.NullReferenceException
Message: Object reference not set to an instance of an object.
Source: System.Web.Extensions

Instant mistake. All the methods on the Controller have the [ControllerAction] attribute and a number of dependencies exist behind the scenes.

At this point, I referred to Phil Haack’s post on Writing Unit Tests for Controller Actions (sounds like what i’m doing). What Phil describes is to use a ‘Test specific subclass’. Using his approach, I change my test to interact with HomeControllerTester

[Test]
public void IndexTest()
{
HomeControllerTester controller = new HomeControllerTester();
controller.Index();
}

I then create the HomeControllerTester which overrides the RenderView method and stores the name in a property.

internal class HomeControllerTester : HomeController
{
public string RenderViewAction { get; private set; }
protected override void RenderView(string viewName, string masterName, object viewData)
{
RenderViewAction = viewName;
}
}

I can then include a Assert.AreEqual(“Index”, controller.RenderViewAction); to ensure the correct view is called. This is easy, but it is additional work just to verify that the correct view is being called.

Another approach he mentioned was using Rhino Mocks, which I have used once or twice before in previous posts. However, it appears as if that support for mocking the RenderView method in this CTP is broken. The only approach is to use the subclass above.

Outputting data

Next thing I wanted to try was creating data within the controller and passing it to the view for outputting.

Within my index method, I just create a dummy generic list of strings which I want to output.

[ControllerAction]
public void Index()
{
List topics = new List();
topics.Add(“My String 1”);
topics.Add(“My String 2”);
topics.Add(“My String 3”);
topics.Add(“My String 4”);
RenderView(“Index”, topics);
}

When calling RenderView, I pass in the generic list as an argument. Now, I just need to output the data. Within index.aspx, I added the following code snippet. This

Outputting data

    <% foreach(string s in ViewData as System.Collections.Generic.List)
    {
    %>

  • <%= s %>
  • <% }

    %>

However, with this I got a compiler error message.

Compiler Error Message: CS0039: Cannot convert type ‘System.Web.Mvc.ViewData’ to ‘System.Collections.Generic.List‘ via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

Looking at the ViewData within the debug view, it has added a _data block and each element within my list is a separate item. However, I couldn’t find a way to extract that data as _data is a private member. The only way to extract the data is based on a name.

image

Within my controller, I changed the code to setup the ViewData

ViewData[“Topics”] = topics;
RenderView(“Index”);

I then changed my output code to be the following:

foreach(string s in ViewData[“Topics”] as System.Collections.Generic.List)

The data is then correctly outputted to the screen.

image

The debug window then looks as I expect with _data containing the generic list.

image

I’m guessing the ViewData constructor is used for something else or its a bug in the rendering. In the documentation, it does say we this is valid syntax:

[ControllerAction]
public void Categories()
{
List categories = northwind.GetCategories();
RenderView(“Categories”, categories);
}

Strange! Moving on, referring object is so .Net 1.1. I want to work with strongly typed objects. The first thing I want to do is create the object

public class TopicsViewData
{
private List topics = new List();
public List Topics
{
get { return topics;}
}
}

This will store all of my view data. I can then change my Index code to use the ViewData object.

[ControllerAction]
public void Index()
{
TopicsViewData viewData = new TopicsViewData();
viewData.Topics.Add(“My String 1”);
viewData.Topics.Add(“My String 2”);
viewData.Topics.Add(“My String 3”);
viewData.Topics.Add(“My String 4”);
RenderView(“Index”, viewData);
}

I then pass in the viewData object as the parameter, which works fine. Within Index.aspx.cs (yes, MVC still has code behind, its just used less often) I change what the page is inheriting from. In the previous version, it simply inherited from ViewPage.

public partial class Index : ViewPage

However, to use a custom View Data object we need to use the generic ViewPage and pass in the ViewData object.

public partial class Index : ViewPage

We can now access all the properties of TopicsViewData from within Index.aspx

<% foreach(string s in ViewData.Topics) { %>

  • <%= s %>
  • <% } %>

    Bit of additional work, but does make it a lot easier to work with.

    MVCToolkit

    The MVCToolkit has the following (according to the readme):

    “- Rendering helpers which make it easier to output various HTML tags in MVC Views

    Dynamic Data support: this gives ASP.NET MVC a powerful and extensible scaffolding architecture. The toolkit also adds metadata pluggability, which allows the metadata used by Dynamic Data to use alternate stores (instead of the default attribute based mechanism).”

    One thing not mentioned is that it includes the Blog sample application which uses the Dynamic Data support controls. Subject for another post…

    Documentation

    There is a bit of documentation over at http://quickstarts.asp.net/3-5-extensions/

    Summary

    In summary, this was just a very quick look at wjats om the CTP, the framework is still very early in the development. Some of the concepts are there and its at the level I expected for thisw CTP. Still worth looking at and having a play. I’ll post more as I find things out.

    One thing I have quickly realised is that I have a lot of reading and work to do to get up to speed with MVC, IoC and how to other MVC frameworks (Monorail) interact. Don’t worry – I’ll be blogging my learning and experience.

    Download MVC: http://www.microsoft.com/downloads/details.aspx?FamilyId=A9C6BC06-B894-4B11-8300-35BD2F8FC908&displaylang=en

    Download MVC Toolkit: http://asp.net/downloads/3.5-extensions/MVCToolkit.zip

    Technorati Tags: ,

    How To Unit Test – Linq to SQL and Mocking

    All problems in computer science can be solved by another level of indirection Butler Lampson (Or Abstraction as some people refer to it as)

    Over the last few posts, I have been covering how to unit test various topics, in this post I will cover Linq to SQL. I’ve been thinking about this for a while, but never had chance to post about it. Various people have spoken about this before, but I thought I would give my view.  I’m going to discuss how to unit test systems involving Linq to SQL, how to mock Linq to SQL, how this will come into play with the new ASP.net MVC Framework and how TypeMock might have the answer.

    Scenario

    For this post, I decided to implement a small part of a shopping cart.  You can return a list of categories, a list of products for each category and the product itself.

    Unit Testing Linq to SQL

    In my previous post, I discussed how to unit test Linq to XML and mentioned how it really isn’t that different to any other system.  Linq to SQL is similar in the fact that you can easily ignore the underneath implementation (Linq) when unit testing, however I’m going to focus more on how to decide the system and how it all should hang together.

    Like in any Linq to SQL implementation you will need a data context.  While you could unit test this implementation, I always prefer to test it as part of a higher layer as its generated code to give the tests more context and more meaningful for the system. The most important part of the system will be how we actually access the DataContext, retrieve the data and make sure that it can be effectively unit tested.

    In my system I will have my HowToUnitTestDataContext generated by the Linq to SQL Designer.  I will then have a ProductController which will talk to my DataContext and return the generated object. Unlike with SubSonic, we can return the designer generated objects as they are just POCO (Plain Old C# Objects).  I will then have a set of unit tests targeting the ProductController.  We are not doing any mocking at this point and all of our unit tests will hit the database.

    First test, create a data context and ensure it has a connection string.  This ensures everything is setup correctly.

    [Test]
    public void CreateDataContext_ConnectionString_ReturnsDataContextObject()
    {
        HowToUnitTestDataContext db = ProductController.CreateDataContext();
        Assert.IsNotNull(db);
        Assert.IsNotNull(db.Connection);
    }

    All the method does is initialise a data context and return it to the caller. The next test requests a list of all the categories from the database.  However, because we haven’t populated anything yet it should just return an empty list.

    [Test]
    public void GetCategories_NoContent_ReturnEmptyList()
    {
        List categories = ProductController.GetCategories();
        Assert.IsNotNull(categories);
        Assert.AreEqual(0, categories.Count);
    }

    We now have a base structure in place and can start filling in the details. The following test first inserts a category into the database (code is in the solution which you can download at the bottom of the post).  It then requests all the categories from the database and ensures that what we returned was correct. We then use the MbUnit RollBack feature to ensure the database is left in the same state as it was before the test. The rollback works perfectly with Linq to SQL!

    [Test]
    [RollBack]
    public void GetCategories_SimpleContent_ReturnPopulatedList()
    {
        InsertCategory();

        List categories = ProductController.GetCategories();
        Assert.IsNotNull(categories);
        Assert.AreEqual(1, categories.Count);
        Assert.AreEqual(“Microsoft Software”, categories[0].Title);
    }

    The code for GetCategories() is a simply Linq to SQL statement which returns a generic list.

    public static List GetCategories()
    {
        HowToUnitTestDataContext db = CreateDataContext();
        var query = from c in db.Categories
                           select c;
        return query.ToList();
    }

    The next important test is the one which returns product information.  Here, we use a tested GetCategory method to return a particular category. We then insert a temp product into the database for that category, meaning that we now have a known database state to work with. The test then simply verifies that when given a category we can return all the products in the database for it.

    [Test]
    [RollBack]
    public void GetProductsForCateogry_ValidCategoryWithProduct_PopulatedList()
    {
        InsertCategory();

        Category c = ProductController.GetCategory(“Microsoft Software”);
        InsertProduct(c);

        List products = ProductController.GetProductsForCategory(c);
        Assert.AreEqual(1, products.Count);
        Assert.AreEqual(“Visual Studio 2008”, products[0].Title);
    }

    The implementation of this method is a little bit more complex as it joins a ProductCategories table to return the products within the particular category.

    public static List GetProductsForCategory(Category c)
    {
        HowToUnitTestDataContext db = CreateDataContext();
        var query = from p in db.Products
                           join pc in db.ProductCategories on p.id equals pc.ProductID
                           where pc.CategoryID == c.id
                           select p;

        return query.ToList();
    }

    The final method is to return a particular product based on its ID.  It works in a similar fashion to the previous methods.

    [Test]
    [RollBack]
    public void GetProductByID_ValidProductID_ReturnProductID()
    {
        InsertCategory();

        Category c = ProductController.GetCategory(“Microsoft Software”);
        InsertProduct(c);

        List products = ProductController.GetProductsForCategory(c);
        Assert.AreEqual(1, products.Count);

        Product p = ProductController.GetProduct(products[0].id);
        Assert.AreEqual(p.Title, products[0].Title);
    }

    In the implementation we then just return a single product using a lambda expression.

    public static Product GetProduct(int productID)
    {
        HowToUnitTestDataContext db = CreateDataContext();

        Product product = db.Products.Single(p => p.id == productID);
        return product;
    }

    That pretty much covers unit testing basic Linq to SQL. Other parts of the system, such as the business layer or UI layer, can then talk directly to the ProductController to return all the information. However, this doesn’t offer anything if you want to mock out Linq to SQL.

    Mocking Linq to SQL

    Unit testing Linq to SQL isn’t very difficult, however mocking Linq to SQL is a different beast. As with SubSonic, the best approach to take is to abstract away from your database. In this case, I am going to add an additional layer in between my ProductController and my DataContext called LinqProductRepository which can then be mocked. 

    My first set of tests are focused on testing the LinqProductRepository which talks to my DataContext and as such my database. The tests are very similar to the above tests for ProductController. I always test this against the database to ensure that it will work effectively when its in production/live, with mock objects you can never have the same level of confidence.

    LinqProductRepository m_ProductRepository = new LinqProductRepository();
    [Test]
    [RollBack]
    public void GetCategoryByName_NameOfValidCategory_ReturnCategoryObject()
    {
        InsertCategory();

        Category c = m_ProductRepository.GetCategory(“Microsoft Software”);

        Assert.AreEqual(“Microsoft Software”, c.Title);
        Assert.AreEqual(“All the latest Microsoft releases.”, c.Description);
    }

    To give you an idea of the implementation, the GetCategory method looks like this:

    public Category GetCategory(string categoryTitle)
    {
        using (HowToUnitTestDataContext db = CreateDataContext())
        {
            Category category = db.Categories.Single(c => c.Title == categoryTitle);
            return category;
        }
    }

    In order to make the ProductRepository mockable it is required to implement an interface.  The interface is very simply, as shown:

    public interface IProductRepository
    {
        List GetCategories();
        Category GetCategory(string categoryTitle);
        List GetProductsForCategory(Category c);
        Product GetProduct(int productID);
    }

    We now have a fully implemented and tested ProductRepository so we can create the ProductController. To start with, in my ProductControllerTests I setup the variables and the [Setup] method for each test.  This ensures that we have our MockRepository (via RhinoMocks) to hand, a copy of our mocked IProductRepository together with our stub category and product.  These two objects are simple well known objects (for the system) which we will return from our mocked methods.  I’m using parameter injection to set the mocked repository on the ProductController which will be used during the tests. By using a parameter we can have a default implementation for our production code but a way for our test code to injection the mock object.

    MockRepository m_Mocks;
    IProductRepository m_ProductRepos;
    Category m_MockedCategory;
    Product m_MockedProduct;

    [SetUp]
    public void Setup()
    {
        m_Mocks = new MockRepository();
        m_ProductRepos = m_Mocks.CreateMock();
        ProductController.ProductRepository = m_ProductRepos;

        m_MockedCategory = MockCategory();
        m_MockedProduct = MockProduct();
    }

    We can then write our unit tests based on this information which will be similar to our previous units tests as they are implementing the same requirements. Within this test, we setup our expected return for the method GetCategories on our ProductRepository, this simply uses C# 3.0 Collection Initialises to create a list with one item, the stub category. We can then execute our test/asserts against the ProductController to view it is all linked correctly and working as expected.

    [Test]
    public void GetCategories_SimpleContent_ReturnPopulatedList()
    {
        using (m_Mocks.Record())
        {
            Expect.Call(m_ProductRepos.GetCategories()).Return(new List { m_MockedCategory });
        }

        using (m_Mocks.Playback())
        {
            List categories = ProductController.GetCategories();
            Assert.IsNotNull(categories);
            Assert.AreEqual(1, categories.Count);
            Assert.AreEqual(“Microsoft Software”, categories[0].Title);
        }
    }

    The ProductController simply passes the call onto our ProductRepository, which is set using a parameter in our test Setup.

    private static IProductRepository m_ProductRep = new LinqProductRepository();

    public static IProductRepository ProductRepository
    {
        get { return m_ProductRep; }
        set { m_ProductRep = value; }
    }

    public static List GetCategories()
    {
        return ProductRepository.GetCategories();
    }

    This allows us to use the ProductController with a mock object. ProductController could be/do anything and by going via the LinqProductRepository we can use mock objects to save us accessing the database.  In our real system, we would use the real tested LinqProductRepository object.

    ASP.net MVC and Linq to SQL

    Recently there has been a lot of buzz around the new ASP.net MVC framework the ASP.net team are releasing (CTP soon).  If you haven’t read about this, Scott Guthrie has done a great post on the subject.

    However, Scott Hanselman did a demo of the MVC framework at DevConnections and has posted the source code online here – DevConnections And PNPSummit MVC Demos Source Code. Demo 3 and 4 is about TDD and uses mock objects and Linq to SQL.

    The layout is as follows:

    ASP.net MVC

    The BlogController talks to a IPostRepository object which is either LinqPostRepository or TestPostRepository. They use a Stub object instead of a mock object, but the architecture is the same as my system. I would just like to say I didn’t just copy them 🙂

    From this demo code, it looks like the way to mock your data access layer will be to use this approach.

    Mocking the DataContext

    The thing which first struck me about this was why couldn’t we just mock the DataContext itself instead of messing around with Repositories and Controllers. The first answer was that it didn’t implement an interface, but that’s a simple fix.  The second problem is that the data context returns everything as System.Data.Linq.Table<>, and this cannot be mocked. It does implement an ITable interface, however you cannot cast another object implementing ITable to Table.

    Ayende, creator of Rhino Mocks, wrote a post called Awkward Testability for Linq for SQL which covers why it cannot be mocked.  Its a shame the Linq team didn’t think about TDD and Mocking the repository as it would have made a big difference to the system design. Maybe this is a lesson for anyone creating an API at the moment – think about testability! I think the ASP.net team have realised this.

    Mocking with TypeMock

    That all said, it looks like TypeMock might be able to provide an answer.  TypeMock is a mocking framework, however is extremely powerful as it can mock any object within your system, it doesn’t care about the implementation or if there is an interface available. It can simply mock anything.  I will be looking at TypeMock more over the next few weeks, but before then visit their site. It’s not free (30 day trail available), but if you need to do this type of mocking then it really is your only solution and it can greatly increase your test coverage and your test suite as a whole.

    You can read the initial ideas over on their blog – Eli Lopian’s Blog (TypeMock) » Blog Archive » Mocking Linq – Preview.  Going in depth on TypeMock and Linq deserves its own post, however I couldn’t resist posting some code now.

    Below, we have a test which mocks out querying a simple list.  Here, we have a list of customers and a dummydata collection. Our actual Linq query is against the m_CustomerList, however TypeMock does some ‘magic’ under the covers and tells the CLR that the query should just return the dummyData. As such, instead of just returning the one customer record, we are returning the two dummy data records. How cool!!!

    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string City { get; set; }
    }

    [Test]
    [VerifyMocks]
    public void MockList()
    {
        List m_CustomerList = new List {
            new Customer{ Id = 1, Name=”Dave”, City=”Sarasota” },
            new Customer{ Id = 2, Name=”John”, City=”Tampa” },
            new Customer{ Id = 3, Name=”Abe”, City=”Miami” }
        };

        var dummyData = new[] {new {Name=”fake”,City=”typemock”},
                   new {Name=”another”,City=”typemock”}};
        using (RecordExpectations recorder = RecorderManager.StartRecording())
        {
            // Mock Linq
            var queryResult = from c in m_CustomerList
                              where c.City == “Sarasota”
                              select new { c.Name, c.City };
            // return fake results
            recorder.Return(dummyData);
        }

        var actual =  from c in m_CustomerList
                      where c.City == “Sarasota”
                      select new { c.Name, c.City };
        Assert.AreEqual(2, actual.Count());
    }

    But it gets better!  Given our original ProductController (no repositories, mocks, fakes, stubs) we can tell TypeMock that for this statement, always return the dummyData. As such, the ProductController never hits the database.

    [Test]
    [VerifyMocks]
    public void MockDataContext()
    {
        Category category = new Category();
        category.id = 1;
        category.Title = “Test”;
        category.Description = “Testing”;

        List dummyData = new List { category };
        using (RecordExpectations r = RecorderManager.StartRecording())
        {
            // Mock Linq
            List mocked = ProductController.GetCategories();
            // return fake results
            r.Return(dummyData);
        }

        List categories = ProductController.GetCategories();
        Assert.AreEqual(1, categories.Count);
        Assert.AreEqual(“Test”, categories[0].Title);
        Assert.AreEqual(“Testing”, categories[0].Description);
    }

    Feel free to download the solution and debug the methods to see it for yourself, I think its cool.

    Summary

    In summary, I hope you have found this post useful and interesting. I’ve covered how to unit test your Linq to SQL code and how you go about mocking Linq to SQL. I then finished by giving you a quick look at what TypeMock can offer. It is possible to mock Linq to SQL, however it’s not as simple as it could be. If you have any questions, please feel free to contact me.

    Download Solutions – TestingLinqToSQL.zip | TestingLinqToSQLMock.zip | TestingLinqToSQLTypeMock