- Posted by dan on January 11, 2013
Hi, I've recently been getting quite into NancyFx. I've written a quickstart NancyFx tutorial if you've interested and even a NancyFx screencast.
Next I thought I'd do a very short followup on testing in NancyFx.
Before you start
Download Nancy Tutorial with testing source code from GitHub
Step 1 - Create a clean NancyBootstrapper
In the previous NancyFx tutorial, I hastily advocated overriding the ApplicationStartup and subscribing to the Error pipeline. Unfortunately this was also mixed in with the StructureMap Bootstrapper. So to seperate those concerns and make it so we can easily inject a Stub NancyBootstrapper.
Your new NancyBootstrapper should look like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using Nancy;
using Nancy.Bootstrappers.StructureMap;
namespace NancyTutorial
{
public class NancyBootstrapper : StructureMapNancyBootstrapper
{
protected override void ConfigureApplicationContainer(StructureMap.IContainer existingContainer)
{
StructureMapContainer.Configure(existingContainer);
}
}
}
Step 2 - Create a class that implements IApplicationStartup
Next we're going to create a CarNotFoundExceptionErrorPipeline this class will simply hook the error pipeline and and some code to check whether the exception is of type CarNotFound and if so it'll return a 404 Not Found Error.
It should look like this:
using System.Text;
using Nancy;
using Nancy.Bootstrapper;
namespace NancyTutorial
{
public class CarNotFoundExceptionErrorPipeline : IApplicationStartup
{
public void Initialize(IPipelines pipelines)
{
pipelines.OnError += (context, exception) =>
{
if (exception is CarNotFoundException)
return new Response
{
StatusCode = HttpStatusCode.NotFound,
ContentType = "text/html",
Contents = (stream) =>
{
var errorMessage =
Encoding.UTF8.GetBytes(
exception.Message);
stream.Write(errorMessage, 0,
errorMessage.Length);
}
};
return HttpStatusCode.InternalServerError;
};
}
}
}
Step 3 - Create a Tests Project
Now we simply need to create a Test project class library. Mines very originally called NancyTutorial.Web.Tests
NancyFx comes with a really nice, simple and best of all fast module called Nancy.Testing this does away with a lot of the need to use WebClient or WebRequest. Which makes life considerably easier, hopefully it'll help make your testing easier to read and thus more maintainable.

Step 4 - Create a simple Test using Nancy.Testing
Since we've only got 1 module in our project called CarModule I'm going to follow the lead and call the test class CarModuleTests. As the Nuget picture above shows we'll also be using trusty old NUnit and Moq to help us with testing our module.
Our first test will exercise the /car/123 endpoint. When we call it we'll expect back an Xml representation of a car, because we will explicity tell the server via the accept headers that we want application/xml. Nancy.Testing makes this really easy for us.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Moq;
using NUnit.Framework;
using Nancy;
using Nancy.Testing;
namespace NancyTutorial.Web.Tests
{
[TestFixture]
public class CarModuleTests
{
[Test]
public void Should_return_car_as_xml_when_present()
{
//Given
var mockRepository = new Mock<ICarRepository>();
mockRepository.Setup(x => x.GetById(123)).Returns(new Car
{
Id = 123,
Make = "Tesla",
Model = "Model S"
});
var browser = new Browser((c) => c.Module<CarModule>()
.Dependency<ICarRepository>(mockRepository.Object));
//When
var response = browser.Get("/car/123", with =>
{
with.HttpRequest();
with.Header("accept", "application/xml");
});
var responseBody = response.BodyAsXml();
//Then
Assert.That(response,Is.Not.Null);
string make = responseBody.Element("Car").Element("Make").Value;
Assert.That(make,Is.EqualTo("Tesla"));
}
}
}
Step 5 - Mock the repository
So if we look at the code above, we firstly decide to mock an ICarRepository this is because we want to control what the repository hands back since we don't want this test talking to a real database (Not that this example even has one). We setup an expectation that the repository will have it's GetCarById(123) method called with an id of 123 and as you can see we hard code the return of a Tesla Model S with Id of 123.
Step 6 - Crete a Nancy testing Browser
Now this is where it gets cool. We create a Browser type (which is from Nancy testing and we pass it a lambda that is equivilent to a ConfigurableBootstrapper. All we do is for the CarModule with it's dependency on ICarRepository that we use a mock repository instead of the real one which would be resovled had we used the "real" NancyBootsrapper class.
Step 7 - call browser.Get()
Looking at the code again, you can see we call the browser.Get("/url") method. Nancy testing of course has all the relevant verbs such as browser.Post and browser.Delete. The second parameter is the interesting bit. It's another lambda. It lets us control properties of the requesting Nancy browser. For example above you see we've set this request to be over Http via the with.HttpRequest() and helpfully we've hinted to the server that we can accept application/xml and we therefore will expect a response in xml.
There's another really helpful one call with.Query() which is how you put items on the querystring. Don't try just putting them in the get, it won't work, because that's todo with Nancy routing as far as Nancy testings concerned.
Step 8 - Assert away
We can also see that there's a multitude of handy extension methods such as the used above response.BodyAsXml() which takes the body response and gives us an XDocument in return.
Step 9 - Testing the response when we throw an exception
Next we'll write a simple test to check that, the above code whereby we moved the error handling code into a new class called CarNotFoundExceptionErrorPipeline is actually working.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Moq;
using NUnit.Framework;
using Nancy;
using Nancy.Testing;
namespace NancyTutorial.Web.Tests
{
[TestFixture]
public class CarModuleTests
{
[Test]
public void Should_return_car_as_xml_when_present()
{
//Given
var mockRepository = new Mock();
mockRepository.Setup(x => x.GetById(123)).Returns(new Car
{
Id = 123,
Make = "Tesla",
Model = "Model S"
});
var browser = new Browser((c) => c.Module()
.Dependency(mockRepository.Object));
//When
var response = browser.Get("/car/123", with =>
{
with.HttpRequest();
with.Header("accept", "application/xml");
});
var responseBody = response.BodyAsXml();
//Then
Assert.That(response,Is.Not.Null);
string make = responseBody.Element("Car").Element("Make").Value;
Assert.That(make,Is.EqualTo("Tesla"));
}
[Test]
public void Should_return_404_NotFound_when_CarRespository_throws_NotFoundException()
{
//Given
var mockRepository = new Mock();
mockRepository.Setup(x => x.GetById(111)).Throws(new CarNotFoundException("Car with Id 111 Not Found"));
var browser = new Browser((c) => c.Module<CarModule>()
.Dependency<ICarRepository>(mockRepository.Object));
//When
var response = browser.Get("/car/111", with =>
{
with.HttpRequest();
with.Header("accept", "application/xml");
});
var responseBody = response.Body.AsString();
//Then
Assert.That(response.StatusCode,Is.EqualTo(HttpStatusCode.NotFound));
Assert.That(responseBody, Is.EqualTo("Car with Id 111 Not Found"));
}
}
}
If we look at the 2nd test listed above Should_return_404_NotFound_when_CarRespository_throws_NotFoundException() we can see that it's much the same as the first but with some simple modifications.
Firstly instead of returning a car we hard code the repository to throw a CarNotFoundException we then use the ConfigurableNancyBootsrapper lambda to resolve the CarModule dependency on ICarRepository to our mocked repository. combined with our mocked throwing of the exception we call Get on the enpoint.
Not we use another handy extension method response.Body.AsString() to convert the response into a simple string. We then assert that the code is correctly functioning by checking the http status code is indeed 404 Not Found and that the error message is correct.
Conclusion
That's it for a brief introduction to Nancy testing. As you can see it's really ncie and simple.
References
I highly recommend checking out the Nancy Testing Documentation for a more Nancy testing examples.
Thanks for reading Dan
- Posted by dan on March 8, 2011
So firstly we should say what a Non-Functional Requirement (NFR) is.
"A non-functional requirement is a requirement that specifies criteria that can be used to judge the operation of a system, rather than specific behaviors. This should be contrasted with functional requirements that define specific behavior or functions. The plan for implementing functional requirements is detailed in the system design. The plan for implementing non-functional requirements is detailed in the system architecture". - Wikipedia paraphrase
What NFR's encompass

It seems that you can have NFR's for practically anything and I feel that there's a considerable gap in the way we capture the requirements of our system. I'm a firm believer in "If it's a required, then it should be tested". But somethings on the NFR list are quite difficult to write an automated test for. for example:
- Performance
- Maintainability
- Security
- Accessibility
- Testability
- Supportability
- Usability
- Price
It's no-wonder that NFR's are often refered to as the "*ilities" .
Quality Attributes
Non-funtional requirements are also referred to as the quality attributes. Before you get upset, it doesn't mean to say all those unit tests having nothing to do with quality, they help ensure that the product indeed does what it's supposed to. But they probably don't measure the performance or the usability of the product.
Somehow after doing Scrum for years now, I'm brought right back to this picture from the Scrum Master training.

The picture, shows, that the customer wanted a tyre hanging from the tree. But even this doesn't specify how heavy the customer is. Can the tyre (or the tree for that matter) continue to function under high load.
Recently my team has been slaving away on an internal tool ready for release day. No we're not quite at the level of Continuous Delivery to release that often, we have a fixed date we work to.
The project had gone really well, we were pair programming using TDD and BDD for the higher level acceptance tests. Our product owners was closely involved, it was as close to the perfect project as I've had in recent time. But there was one thing I overlooked.
Don't Forget the Non-Functional Requirements (NFR's)
For all the good the above mentioned techniques have brought us, None of it could of been deployed at any time, which is a goal of Scrum and many of the Agile development methodologies. The reason why because we hadn't seperated out of Data Access Code into a seperate process. Now please don't confuse this with not seperating it out into a seperate layer. It was a seperate layer, but ultimately it would of run under the same IIS worker process as the rest of our application and we have an NFR that for security says that Data Access must be performed in a seperate process.
This is completely understandable for a public facing website, but our tool was for internal use only.
What's Your Definition of Done
Your definition of done, might say:
- All software must be maintainable
- All software must be highly performant
- Must function under high load
But are these points really that helpful. Does an internal tool that's destined to by used by a team of 10 people really need to be able to function under high load? Probably not in this case and thus we highlight the problem with generic NFR's, they just might not be applicable. But if we follow the definition of done we end delaying our delivery of value.
A Possible Answer
Well maybe with all things Agile or scrum is another type of card such as the
NFR Card. I can't claim it as my idea, only one I'll try now I've read, this great post on
understanding non-functional requirements. The key is as with the
User Stories or
BDD Scenarios is that the card should offer something concrete and measureable. Of course somethings are very difficult to quantify, like usability or supportability. Try and make them quantifiable, lifes much easier if they are.
Monitoring Metrics
Some NFR's it might be better to elect to have them as qualities or attributes that are monitored and measured over time. Usability could be measured by increase in conversion. Supportability could be measured by a qualitive survey on how supportable it is. Obviously quantitive measures are better. But if these NFR's are really that important then we should be able to monitor the quality it's there to ensure.
How do other's deal with NFR's? Should they be negotiable by the team with the architecture team. Or should the team decide on the NFR's.
References