Latest

You are testing, right? Have you ever used a mock in your test? When testing a class, a mock allows you to create an object that looks just like an object that your class depends on, but acts in a very specific way that you specify for your test, so that you can test your class completely isolated from the rest of your code. If you’re not familiar with mocks, visit Moq’s quickstart guide to get started.

Now that you know about mocks, let’s look at mocking something a little more complicated. If you’ve ever wanted to unit test a method that uses a DbSet<T> to retrieve data, it can be challenging to figure out how to properly mock the DbSet<T>.

Suppose your code looked like this:

public class MyDbContext : DbContext
{
    // Needs to be virtual so that our mocked item can override it
    public virtual DbSet<Customer> Customers { get; set; }
}

public class Repository
{
    private MyDbContext context;

    public Repository(MyDbContext context)
    {
        this.context = context;
    }

    // The method you want to test
    public bool FindCustomersByPostalCode(string postalCode)
    {
        return context.Customers.Where(c => c.PostalCode == postalCode);
    }
}

With Moq for mocking, you might start my creating a mocked object:

var mockedContext = new Mock<MyDbContext>();
mockedContext.Setup(c => c.Customers).Returns( ??? );

But how do you set it up? There are 3 properties and a method you need to mock inside a DbSet<T> to properly mock it: Provider, Expression, ElementType, and GetEnumerator(). I put together the following extension methods to make it easy to mock a DbSet<T>:

public static class DbSetMocking
{
    private static Mock<DbSet<T>> CreateMockSet<T>(IQueryable<T> data)
            where T : class
    {
        var queryableData = data.AsQueryable();
        var mockSet = new Mock<DbSet<T>>();
        mockSet.As<IQueryable<T>>().Setup(m => m.Provider)
                .Returns(queryableData.Provider);
        mockSet.As<IQueryable<T>>().Setup(m => m.Expression)
                .Returns(queryableData.Expression);
        mockSet.As<IQueryable<T>>().Setup(m => m.ElementType)
                .Returns(queryableData.ElementType);
        mockSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator())
                .Returns(queryableData.GetEnumerator());
        return mockSet;
    }

    public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(
            this IReturns<TContext, DbSet<TEntity>> setup,
            TEntity[] entities)
        where TEntity : class
        where TContext : DbContext
    {
        var mockSet = CreateMockSet(entities.AsQueryable());
        return setup.Returns(mockSet.Object);
    }

    public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(
            this IReturns<TContext, DbSet<TEntity>> setup,
            IQueryable<TEntity> entities)
        where TEntity : class
        where TContext : DbContext
    {
        var mockSet = CreateMockSet(entities);
        return setup.Returns(mockSet.Object);
    }

    public static IReturnsResult<TContext> ReturnsDbSet<TEntity, TContext>(
            this IReturns<TContext, DbSet<TEntity>> setup,
            IEnumerable<TEntity> entities)
        where TEntity : class
        where TContext : DbContext
    {
        var mockSet = CreateMockSet(entities.AsQueryable());
        return setup.Returns(mockSet.Object);
    }
}

To use this, first create some sample data that the mocked DbSet<T> will return. This data can be in an Array<T>, IQueryable<T>, or anything that implements IEnumerable<T>, such as a List<T>. Then create and setup the mocked DbSet<Customer>. Note the use of the new ReturnsDbSet extension method:

var fakeCustomers = new Customer[]
{
    new Customer() { Name = "George", PostalCode = "01523" },
    new Customer() { Name = "Susan", PostalCode = "12345" }
}

var mockedContext = new Mock<MyDbContext>();
mockedContext.Setup(c => c.Customers).ReturnsDbSet(fakeCustomers);

Now your mocked context is ready to be used in your test.

var repository = new Repository(mockedContext.object);
var result = repository.FindCustomersByPostalCode("01523");

// Using Fluent Assertions
result.Single().Name.Should().Be("George");

References:
http://msdn.microsoft.com/en-us/data/dn314429.aspx
http://aikmeng.com/post/62817541825/how-to-mock-dbcontext-and-dbset-with-moq-for-unit

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

Overview

A few weeks ago I wrote an article called Cleaning Up EF 6 Tests With Transactions Rollbacks, where I showed how to create integration tests that set up some data in a database, run a test against the data, and then roll back all changes to the data. The rollback was possible because all of the changes to the data were wrapped up inside a transaction.

This posts extends that idea, but instead of a test calling methods on a repository or service layer, this test makes an HTTP call against a Web API endpoint, while preserving the ability to revert all changes to the database as part of a transaction rollback.

The interesting part here is that we will create a database context, start a transaction against that context, create some test data, and then spin up a Web API server that uses that same context. When we’re done with our tests, we’ll roll back the transaction so that the database changes are all reverted.

Base API Test Class

First, let’s look at the TransactionTest class that we created earlier. If you haven’t seen this before, I’d recommend reviewing my earlier post.

[TestClass]
public class TransactionTest
{
  protected EntitiesV3 context;
  protected DbContextTransaction transaction;

  [AssemblyInitialize]
  public static void AssemblyStart(TestContext testContext)
  {
    RetryDbConfiguration.SuspendExecutionStrategy = true;
  }

  [TestInitialize]
  public void TransactionTestStart()
  {
    context = new EntitiesV3();
    transaction = context.Database.BeginTransaction();
  }

  [TestCleanup]
  public void TransactionTestEnd()
  {
    transaction.Rollback();
    transaction.Dispose();
    context.Dispose();
  }

  [AssemblyCleanup]
  public static void AssemblyEnd()
  {
    RetryDbConfiguration.SuspendExecutionStrategy = false;
  }
}

We’ve seen that before. It allows us to create a test inside a database transaction that can be rolled back. How do we extend this to Web API calls? Here is the code:

[TestClass]
public abstract class WebApiHostedTests : TransactionTest
{
    private static HttpServer server;
    private string baseurl = "http://localhost:50366/";
    private HttpClient client;
    private HttpRequestMessage request;
    private HttpResponseMessage response;

    [TestInitialize]
    public void WebApiHostedTestBaseStart()
    {
        var config = new HttpConfiguration();
        config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
        config.Properties["context"] = context;
        WebApiConfig.Register(config);
        server = new HttpServer(config);
        client = new HttpClient(server);
    }

    [TestCleanup]
    public void WebApiHostedTestBaseEnd()
    {
        if (request != null)
        {
            request.Dispose();
            request = null;
        }
        if (response != null)
        {
            response.Dispose();
            response = null;
        }
    }

    protected TestHttpResponse<T> Get<T>(string url)
    {
        request = createRequest<string>(url, "application/json",
            HttpMethod.Get, null, new JsonMediaTypeFormatter());
        response = client.SendAsync(request).Result;
        var data = (T)((ObjectContent)(response.Content)).Value;
        return new TestHttpResponse<T>(response, data);
    }

    private HttpRequestMessage createRequest<T>(string url, string mthv,
        HttpMethod method, T content, MediaTypeFormatter formatter)
        where T : class
    {
        var request = new HttpRequestMessage();
        request.RequestUri = new Uri(baseurl + url);
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(mthv));
        request.Method = method;
        request.Content = new ObjectContent<T>(content, formatter);

        // Add authentication here if needed

        return request;
    }
}

Let’s look at this one piece at a time. First, we have the WebApiHostedTestBaseStart. Because of the [TestStart] attribute, this will be run before each tests is run. Because this class inherits from the TransactionTest class, the TransactionTestStart method has already run, so we have a context ready. The WebApiHostedTestBaseStart does the following:

  • - It creates an HttpConfiguration and adds the context as a property on this configuration. (the Properties property is a collection of arbitrary objects that we can see inside our Web API code. This allows us to pass the context into our Web Api project. We’ll look at that momentarily)
  • - It creates an in-memory HttpServer, which allows us to run our Web API project in the test runner process without having to spin up IIS or any other web server.
  • - It creates an HttpClient and configures it to connect to our in-memory HttpServer.

The WebApiHostedTestBaseEnd method runs after each test is run because of the [TestCleanup] attribute. This cleans up the objects that we created in WebApiHostedTestBaseStart.

The Get method, given a URL, makes a HTTP GET call to the server, receives JSON back from the server, and deserializes the JSON into a strongly typed object of type T. The deserialization happens in this line:

var data = (T)((ObjectContent)(response.Content)).Value;

TestHttpResponse

The Get method then returns a TestHttpResponse, which is an object that contains the strongly typed T along with the raw HTTP response. This allows our test to check the data that was returned, and it allows our test to check the HTTP response codes and headers that are returned. A Web API is composed of many HTTP endpoints that should return various HTTP responses codes, and this allows us to test those response codes.

Here is the implementation of TestHttpResponse:

public class TestHttpResponse<T>
{
    public TestHttpResponse(HttpResponseMessage message, T data)
    {
        this.Message = message;
        this.Data = data;
    }

    public HttpResponseMessage Message { get; private set; }
    public T Data { get; private set; }
}

Context Injection

Next, we’ll make use of the context that this sets up for us. In our API controller, we’ll need to grab the context from our HttpConfiguration. HttpConfiguration is a property on all controllers that inherit from ApiController. Our code above created and then injected the context into the configuration with this line:

config.Properties["context"] = context;

And this is how we can make use of that context in our API Controllers:

if (Configuration == null || Configuration.Properties == null ||
    !Configuration.Properties.ContainsKey("context"))
{
    // No context was passed in from our tests
    // Create our context using the connection string "FooContext"
    context = new FooContext();
}
else
{
    // This is running inside an integration test, so use the context
    // that is provided by the test:
    context = (FooContext)Configuration.Properties["context"];
}

Writing a Test

Now that we have all of these great things set up, how do we use them? We need to create a test class that inherits from WebApiHostedTests:

[TestClass]
public class FooControllerTests : WebApiHostedTests
{
    [TestMethod]
    public void CallingGetItemByNameReturnsItem()
    {
        // Arrange
        context.Items.Add(new Item() {Name = "Thing", Id = 17});
        context.SaveChanges();

        // Act
        var url = string.Format("api/items/{0}", 17);
        var response = Get<Item>(url);

        // Assert
        response.Message.StatusCode.Should().Be(HttpStatusCode.OK);
        response.Data.Id.Should().Be(17);
        response.Data.Name.Should().Be("Thing");
    }
}

The goal of the code in this post is to make these tests simple and readable. The test adds data to your context, makes an HTTP call, specifying what type of data it expects to get back (Item in this case), and it then verifies that the HTTP Response looks good and that the data that is returned looks good. The test itself has minimal boilerplate code, and it cleans up after itself.

Closing

Thanks for sticking with me in this series on Web API. Feel free to tweet me @codethug if you’d like to follow up on anything.

Permalink

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

Data Transfer Objects

First, off what is this DTO thing? A Data Transfer Object is an object structure that you use to transfer data across the wire. Sometimes it will look exactly like your entity framework entities. Sometimes it will be different.

For example, suppose you have a database with Customers and Invoices, and your tables look like this:

Customer Table
--------------
CustomerId
Name
City
Telephone

Invoice Table
-------------
InvoiceId
CustomerId
Amount

These are also what your Entity models look like, because entity models reflect the database structure.

Now suppose that you want to provide an API endpoint that returns a list of customers in a particular city with the number of invoices for each customer. The data you want to return from your API looks like this:

CustomerDTO
-----------
CustomerId
Name
Telephone
InvoiceCount

This is your DTO. You can make out where the data comes from in your database, but there is no table structure in your database that has this exact collection of fields, and thus no entity model that looks exactly like this. You will need to retrieve the data from your database and then map/transform it into this structure.

Manual Mapping

How do you map your data? You can do it manually.

// Get the customers from the database
var customersFromCity = context.Customers
    .Include(c => c.Invoices)
    .Where(c => c.City == city);

// Count the invoices for each customer
var customersWithInvoicesCounted = customersFromCity.Select(c =>
    new CustomerDTO()
    {
        CustomerId = c.CustomerId,
        Name = c.Name
        Telephone = c.Telephone
        InvoiceCount = c.Invoices.Count()
    }
);

This works. But it will become tedious very quickly – you will be writing many, many lines of code that do nothing more than copy a property from an entity to a DTO (and for POSTs/PUTs, you’ll do the same in reverse).

Automapper

Enter Automapper. It is designed specifically to relieve you of this tedium. It involves two steps:

1. Setup Automappper. This can be done once in a centralized location for your entire application. Here is the basic mapping setup:

// Customer is your Entities Customer class, and CustomerDTO is,
// well, your Customer DTO class
Mapper.CreateMap<Customer, CustomerDTO>();

Assuming that the property types and names on the two classes match, Automapper can figure out how to copy properties from one to the other. However, we have one property that can’t be directly copied – the InvoiceCount property. Thankfully, Automapper has a way to help us manually map properties. We just extend the mapping definition a little:

Mapper.CreateMap<Customer, CustomerDTO>()
    .ForMember(dest => dest.InvoiceCount, opt =>
        opt.MapFrom(src => src.Invoices.Count()));

With the ForMember() call, we’re telling Automapper that when it sees the InvoiceCount property on the DTO, it should populate the property by calling Invoices.Count() on the object it’s copying things from. The rest of the properties are figured out automatically.

2. Use Automapper to perform the mappings.

To map a single item:

CustomerDTO customerWithInvoicesCounted = Mapper.Map<CustomerDTO>(customer);

This is nice and simple – there is no need to manually map every single property. However, it’s slightly different when you’re dealing with a collection of items. If you have an IQueryable of customer entities, and you want to ‘preserve the IQueryable‘ if you will, Automapper can still help. Continuing with our example above, where we want to find customers from a specified city and the number of invoices they each have, you can map the data like this:

// Get the customers from the database
var customersFromCity = context.Customers
    .Include(c => c.Invoices)
    .Where(c => c.City == city);

IQueryable<CustomerDTO> customersDTO =
    customersFromCity.Project().To<CustomerDTO>();

Notice what’s going on here – Automapper has just mapped your IQueryable<Customer> into an IQueryable<CustomerDTO> using the mapping instructions defined above. You can then perform a query on this IQueryable<CustomerDTO>, and the query will be executed on your SQL server. Furthermore, if OData URL Query options are turned on, you can return this IQueryable from your Web API endpoint, and the javascript client can control mapping, filtering and paging in your database even though the javascript client can only see the structure of the DTOs.

There are some limitations on what can be projected in this way – see the ‘Supported Mapping options’ section at the bottom of https://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions for details.

Permalink

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

OData URL Query Options

In your API, have you ever created a GET /Orders endpoint, then you discover you need to support paging, so you add an GET /Orders?start={start}&pageSize={pageSize} endpoint? Then you learn another endpoint is needed for sorting by Date, so you also create GET /OrdersByDate and GET /OrdersByDate?start={start}&pageSize={pageSize}  endpoints. Before you know it, even though it feels like it should only be a single method, you end up with a collection of endpoints that all do pretty much the same thing except for basic sorting and filtering.

There is an easier way.

Turn on OData URL Query options. To do this, open App_Start\WebApiConfig.cs and add this to the top of the Register method:

// Allow OData Queries on all methods that return IQueryable
System.Web.Http.OData.Extensions
    .HttpConfigurationExtensions.AddODataQueryFilter(config);

Next, return an IQueryable from your GET /Orders endpoint and consumers of your API can do paging, filtering, and sorting. As long as the IQueryable comes all the way from your Entity Framework context, then the paging, filtering, and sorting is all done where it should be – in the database.

For example, if someone only wanted to get the first 10 orders, they could call /Orders?$top=10. The paging for $top=10 is implemented automatically – you don’t have to implement anything other than returning an IQueryable and turning on OData URL Query Options as described just above.

For more documentation on the OData URL conventions, see http://docs.oasis-open.org/odata/odata/v4.0/os/part2-url-conventions/odata-v4.0-os-part2-url-conventions.html#_Toc372793790. Please note that the technique described in this post does not implement a full OData service – it only uses the querystring structure of OData to allow for filtering, sorting, and paging. A full OData web service can be provided by Web API, but that is beyond the scope of this series.

In the next post in the series, we’ll see how you can return a custom Data Transfer Object (DTO) from your API methods, where the DTO differs from your EF models, but without breaking the functionality provided by OData Query Filtering.

Permalink

Microsoft’s ASP.Net Web API 2.2 allows you to easily create REST style APIs on an IIS website. Microsoft has some great documentation on how to get started with it, so I won’t rehash that here. Instead, I’m going to go a little deeper into some powerful features that can be used with Web API.

HTTP Error Codes from Exceptions

In the last post, we looked at how you can specify HTTP Response codes to return from your API controller when everything is working properly. However, sometimes a problem will occur deep inside your code. Continuing down the REST path, when problems occur, you should use the semantics of HTTP by returning an HTTP status code that reflects the error. When problems occur in your code, exceptions are typically thrown. This week we will be looking at how we can specify the HTTP Response code and content to return depending on the exception that is thrown.

This is a matter of style, but the first thing that I like to do is to create a custom exception, so that I know that what I’m doing will only apply when I specifically raise my custom exception.

public class OrderTotalWrongException : Exception
{
    public OrderTotalWrongException(int orderId, decimal totalOrderAmount,
        string message) : base(message)
    {
        this.OrderId = orderId;
        this.TotalOrderAmount = totalOrderAmount;
    }
    public int OrderId { get; set; }
    public decimal TotalOrderAmount { get; set; }
}

Next, create an ExceptionFilterAttribute. An ExceptionFilterAttribute allows you to handle a exception that is not handled by a controller action. Please note that this attribute can be used with multiple exception types you want to use by adding an ‘else‘ statement after the first ‘if‘ statement.

public class OrderingExceptionResponseAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        if (actionExecutedContext.Exception is OrderTotalWrongException)
        {
            var response = new HttpResponseMessage(HttpStatusCode.Conflict);
            response.ReasonPhrase = "Problem with Order Total";
            var e = (OrderTotalWrongException) context.Exception;
            response.Content = "There is a problem with order " + e.OrderId +
                ".  It showed up with a total of " + TotalOrderAmount;
            context.Response = response;
        }
    }
}

Let’s dig into this code. We’re creating an Exception Filter. This is an attribute that, when applied to a controller or action method, will give this code a chance to handle unexpected exceptions.

We only care about the specific custom exception I created earlier. When it is thrown, we create a HttpResponseMessage – this is the response that will be sent to the client that called our API. Our normal controller and action method can’t help us, because they weren’t able to handle this exception, so it’s up to us to construct a meaningful response. We set the HTTP Status Code – in this case we’re using HTTP 409, Conflict, because there is a conflict with the total amount of the order. http://httpstatus.es has a helpful listing of the available HTTP status codes. I then add some textual description of the error that is built from the properties on the custom Exception type we created earlier, and we set the response on the context object so that the HttpResponseMessage we created will be returned to the client.

Now you have created the attribute that can be added to any controller or action method. Next, you can either manually add it to the controllers you want to add it to, or you can add it to all controllers, all actions, by opening up App_Start\WebApiConfig.cs and adding this line:

config.Filters.Add(new OrderingExceptionResponseAttribute ());

You have now wired up a global exception handler that will kick in and provide a specific HTTP response when an action is called, the custom exception is thrown, and you don’t handle the exception in the action. The nice part about this is that your actions and anything that your actions call don’t need to know that this is in place. All they have to do is throw your custom exception.

[HttpPut, Route("Order/{orderId}")]
public IHttpActionResult UpdateOrder(int orderId, UpdateOrderVM updateOrder)
{
    if (!orders.OrderExists(orderId))
    {
        return new NotFoundResult(Request);
    }

    // The UpdateOrder method has logic that
    // might throw OrderTotalWrongException
    orders.UpdateOrder(updateOrder);
    return Ok();
}

References:
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling
http://stackoverflow.com/questions/15167927/how-do-i-log-all-exceptions-globally-for-a-c-sharp-mvc4-webapi-app
http://www.apress.com/9781430259800
https://github.com/filipw/apress-recipes-webapi/tree/master/Chapter%2007/7-1
http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling