Super Test style testing for .net OWIN web api projects
A small focused library for in memory testing of .net web api projects. Inspiration taken from the excellent Super Test libaray for testing nodejs http servers.
The library is available as a nuget package.
Install-Package NSuperTest
The library allows you to test web api http servers in memory by loading the Startup class using the OWIN self host. The basic object for testing is the ServerClass. You can load up the object using any testing tool and use it to automate requests against a http endpoint and do assertions against the response.
using NSuperTest;
[TestClass]
public void SomeTests
{
static Server<Startup> server;
[ClassInitialize]
public static void Init(TestContext ctx)
{
server = new Server<Startup>();
}
[TestMethod]
public void TestHelloWorldRoute()
{
server.Get("/hello")
.Expect(200)
.End();
}
}
You can also in memory test using a configuration setting. To use this, specify an app setting called nsupertest:appStartup and specify the fully qualified type name for your startup class.
<appSettings>
<add key="nsupertest:appStartup" value="MyLib.StartupMock, MyLib" />
</appSettings
Once this is done you can just create a new server instance and you dont need to supply an standard or generic parameters
static Server server;
[ClassInitialize]
public static void Init(TestContext ctx)
{
server = new Server();
}
Sometimes you just want to run tests against an external API thats hosted somewhere else. The Service objects provides a non generic constructor that takes a Url as a target to help you do that.
static Server server;
[ClassInitialize]
public static void Init(TestContext ctx)
{
server = new Server("http://api.mysite.com:3002/myapi");
}
The api is a fluent API that hangs off the server.verb chain where verb is a standard HTTP verb.
Get is pretty straight forward.
server
.Get("/products")
.Expect(200)
.End();
Post allows you to post a body to the server
var product = new {
Name = "Acme Thing",
Price = 100
};
server
.Post("/products")
.Send(product)
.Expect(201)
.End();
Put allows you to send a body to the server
var product = new {
Name = "Acme Better Thing"
};
server
.Put("/products")
.Send(product)
.Expect(200)
.End();
Does what it says on the tin
server
.Delete("/products/12")
.Expect(204)
.End();
Headers can be set on requests using the Set method
server
.Get("/products")
.Set("Accept", "application/json")
.Expect(200)
.End();
There is also a specific method to allow setting a bearer token
server
.Get("/products")
.SetBearerToken("cC2340xcv")
.Expect(200)
.End();
// ITestBuilder SetBearerToken(Func<string> generator);
// ITestBuilder SetBearerToken(Func<Task<string>> generatorTask);
The SetBearerToken has 3 overloads allowing you to generate the token then and there or farm it off to a Task that will return the bearer token, allowing you to request it from an authentication server using client credentials if possible.
There are 3 ways to assert response status, either via int code, HttpStatusCode enum or via some convenience methods that have been added.
.Expect(200); // Expect ok
.Expect(HttpStatusCode.Ok); // Expect ok
.ExpectOk(); // Expect ok
When you have completed the chain you use the end method to invoke the request and run the assertions. You can also use one of two overloads that allow you to place some custom assertions on the response using the HttpResponseMessage object returned, or a Generic version of End that tries to cast the body into an object.
server
.Get("/products/12")
.Expect(200)
.End<Product>((m, p) => {
Assert.AreEqual(12, p.Id);
});