Available here.
Still trying to get things working, but I’m allready prefering this to the old quicknet way.
Recently I ported the Agatha tests to use quickdotnetcheck and I’m particularely happy with the RequestDispatcher tests.
Here’s how the tests are currently run, though it is certain this will change in the future :
public class RequestDispatcherSuite : Suite
{
public RequestDispatcherSuite() : base(50, 20) { }
[Fact]
public void Verify()
{
Using(() => new RequestDispatcherTestsState());
Register(() => new AddRequest(() => Get<RequestDispatcherTestsState>().RequestDispatcher));
Register(() => new AddRequestArray(() => Get<RequestDispatcherTestsState>().RequestDispatcher));
Register(() => new AddRequestWithKeys(Get<RequestDispatcherTestsState>));
Register(() => new Clear(Get<RequestDispatcherTestsState>));
Run();
}
}
The Suite class is a ‘test runner’ class.
The numbers in the call to the base constructor defines the amount of tests and fixtures to run, similarely to how quicknet handled this.
The Using and Get calls, is just a silly way to pass state around, … still thinking about this part.
The Register calls they, well, … register which fixtures to run, and finally, Run starts the test.
Here’s a simple fixture :
public class AddRequest : RequestDispatcherFixture
{
private Request input;
public AddRequest(Func<RequestDispatcher> requestDispatcher)
: base(requestDispatcher) { }
public override void Arrange()
{
input = new RequestGenerator().One<Request>();
}
protected override void Act()
{
requestDispatcher().Add(input);
}
public Spec TheRequestExistsInTheRequestCollection()
{
return new Spec(() => Ensure.True(requestDispatcher().SentRequests.Any(src => src == input)))
.If(() => RequestTypeNotYetUsed(input.GetType()));
}
public Spec ThrowsExceptionIfRequestTypeAllreadyUsed()
{
return new Spec(Ensure.Throws<InvalidOperationException>)
.If(() => RequestTypeAllreadyUsed(input.GetType()));
}
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendLine(GetType().Name);
sb.AppendFormat(" input : {0}", input.GetType().Name);
return sb.ToString();
}
}
In the Arrange part we supply the input : a random request.
The act part is the method under test and in this case we use the input request and add it to the request dispatcher.
As this is a pretty simple method we’re testing, there’s only two Specs defined :
One that ensures that the request is known to the dispatcher if all goes well.
And another one that ensures an exception is thrown if we try to add the same request type twice.
Overriding the ToString Method is done for reporting issues.
On a side note :
Just as quicknet, quickdotnetcheck forces you to write ‘complete’ specs.
If one were to ommit the spec that ensures the exception, qdnc will tell you about it, like so :
Test 'Tests.RequestDispatcherTests.RequestDispatcherSuite.Verify' failed: QuickDotNetCheck.RunReport :
Ran 1 test, 4 fixtures.
--------------------Simplest Fail Case--------------------
1 : AddRequest
input : FirstRequest
2 : AddRequest
input : FirstRequest
----------------------------------------------------------
---- QuickDotNetCheck.Exceptions.UnexpectedException : Act threw :
System.InvalidOperationException: A request of type Tests.RequestProcessorTests.FirstRequest has already been added. Please add requests of the same type with a different key.
You can have a look at the other fixtures and all here.
One other thing …
…that made me smile during all this porting stuff, is that qdnc uncovered a (very small) bug.
Here’s the report I got :
Ran 1 test, 5 fixtures.
Spec 'AddRequestWithKeys.TheKeyedRequestExistsInTheRequestCollection' does not hold.
--------------------Simplest Fail Case--------------------
1 : AddRequest
input : SecondCachedRequest
2 : AddRequestWithKeys
input :
key : KeyOne
request : SecondCachedRequest
----------------------------------------------------------
A small change to the requestdispatcher made all pass.
- AddRequest(request, true); - keyToTypes[key] = request.GetType(); + keyToTypes[key] = request.GetType(); + AddRequest(request, true);
As I said a small bug, and one that has never surfaced in the wild.
Probably because no-one is using the AddRequest and AddRequestWithKey methods in this way.
Property based testing makes sure that whichever assumption you hold about the way your program behaves, is justified.