SignalR is one of the latest (and sexiest) elements in the .NET stack. Expect to hear more about SignalR if you haven’t already, because it delivers on the promise of push technology without the requirement of a fat client. If you’ve not yet read much about SignalR, clone the source code from GitHub or read Scott Hanselman’s post on SignalR for an introduction. The scope and inner-workings of SignalR are somewhat out of scope here, so I’ll just assume you’ve at least heard something about SignalR and that you’re interested in it but have a few questions. I mean, if you’re into BDD/TDD, you should definitely be wondering:
The Calculator SignalR Hub
This example will offer a solution to the simple problem of providing basic numeric calculations. Obviously, the first operation most users will need is some addition functionality.
The controller action for the client has no special glue or magic in it. It’s basically a shell to adhere to the requirement of having an action for the views.
On the client, there will be a few script references to make sure SignalR works properly.
The call earlier, within the implementation of the Hub, is basically a way of the server telling the client, would you please run this method and pass it this data? It isn’t a really sexy example when you see it execute, of course, but it drives the point home. SignalR makes push ridiculously simple.
Bring on the BDD!
As if SignalR isn’t nifty enough, Jasmine gives us the ability to set up specifications and unit tests to make sure things are working properly and to guide development. Now, we get to put them together to answer the problem of how to test the client. (I’m not knocking other methods, like WaTiN or other automated testing implementations, here, this is just another way of skinning the same kitty.)
We’ll need to include the basic script references and CSS file to make Jasmine light up. You can download those from the Jasmine site, or they’re included in the GitHub repository I’ve created for the purpose of my continued tinkering in SignalR.
Once the specifications have been written up, Jasmine’s environment is created and the tests are executed.
If you’ve pinned the tail on the donkey to this point, the results should be quite self-explanatory when you view the calculator page again. If you don’t see the tests, check the passed checkbox and the passing test will appear.
The first step in getting this working is to modify the test fixture class so it can be supplied any dependencies it might have. In this case, we plan on testing the calculator hub, so it’ll be passed into the fixture in it’s constructor. Also added is the addCallback field. At this point it’ll be set to false, but the plan is, to set this variable to the callback method that will be called when the calculation is completed by the hub.
Since the constructor’s changed it’d be wise to change the calling code, our jQuery ready method. This time, we’ll go ahead and create an instance of the SignalR CalculatorHub and it’ll be provided as a construction argument.
It’d help at this point to take a peek at the Jasmine Wiki article on Spies to get an idea of how this sort of verification can be accomplished. Jasmine’s Fluent syntax makes it pretty self-explanatory (and including vsdoc files to provide Intellisense in Visual Studio brings in the Jasmine methods). Jasmine, like Moq and other mocking frameworks, offers unit tests the capability of checking to see if methods have been executed properly.
If your Jasmine tests are executed at this point, you’ll see some p-r-e-t-t-y interesting results. For about 5 seconds the browser will let you know something’s happening by making the current test’s background color yellow.
Then the test will complete execution and fail. Jasmine is assuming via those calls earlier assume they should wait for an asynchronous response and if it doesn’t arrive, the tests will fail. They fail because the callback methods are never executed, and the tests expect them to be.
Within the test fixture resides the onAdd method. It just executes the fixture’s addCallback method and feeds it the results from the SignalR CalculatorHub call.
Once that’s all wired up, the test should pass!
If you’re obsessive about verifying, just change the expected value to be something wrong and re-run the test. Obviously, if the math fails, so should the test. Otherwise it’d be a pretty useless calculator!
SignalR and Jasmine work quite nicely together. If you apply a little OO elbow grease and take the time to wire things up with callbacks and to verify the execution of those callbacks, SignalR can be tested rather effectively. All it takes is to properly stage, and then verify, that the Hub’s method is called and that, when the Hub fires the client callback, that the callback is executed as your code expects it to be executed.
Thanks for taking the time to stop by. Happy Coding!