Friday, May 15, 2015

Testing .Net C# WebAPI methods with NUnit and HttpResponseMessage

I recently wrote my first NUnit test for a .Net WebAPI controller. I learned two interesting things. (The code has been simplified to be more explicit).

1. When you create your controller, set a value for it's "Request" object.

//helper function to create testable "projects" controller
private ProjectsController GetTestProjectsController()
{
    ProjectsController controller = 
         new ProjectsController(logger, new ProjectRepository())
    {
        Request = new HttpRequestMessage()
        {
            Properties = { { HttpPropertyKeys.HttpConfigurationKey, 
                 new HttpConfiguration() } }
        }
    };
    return controller;
}

2. When retrieving an object use the TryGetContentValue() method to extract the returned value as a C# object. Notice on line 18 we free the C# object from the clutches of the evil HttpResponseMessage object.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[Test]
public void GetTestWithExistingProjectName()
{
    string projectName = "GetTestWithProjectName";
    var projectRepository = new ProjectRepository();

    // Arrange
    DeleteProjectIfItExists(projectRepository, projectName);
    var newTestProject = CreateNewTestProjectAndWriteToRepository(projectName,projectRepository);
    var controller = GetTestProjectsController();

    // Act
    HttpResponseMessage httpResponseMessage = controller.Get(projectName);

    // Assert
    Assert.IsTrue(httpResponseMessage.IsSuccessStatusCode);
    Project project = null;
    httpResponseMessage.TryGetContentValue(out project);
    Assert.AreEqual(projectName, project.Name);

    //cleanup
    DeleteProjectIfItExists(projectRepository, projectName);
}

This is the code for the api GET.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
public HttpResponseMessage Get(string name)
{
    var project = _projectRepository.GetProjectByName(name);
    if (project != null)
    {
        return Request.CreateResponse(HttpStatusCode.OK, project);
    }
    return Request.CreateErrorResponse(HttpStatusCode.NotFound, 
            "Sorry, the project '" + name + "' could not be found.");
}

Special thanks to the folks at hilite.me for their awesome code highlighter site.

No comments: