Unit Testing ASP.NET? ASP.NET unit testing has never been this easy.
Typemock is launching a new product for ASP.NET developers – the ASP.NET Bundle – and for the launch will be giving out FREE licenses to bloggers and their readers.
The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both Typemock Isolator, a unit test tool and Ivonna, the Isolator add-on for ASP.NET unit testing, for a bargain price.
Typemock Isolator is a leading .NET unit testing tool (C# and VB.NET) for many ‘hard to test’ technologies such as SharePoint, ASP.NET, MVC, WCF, WPF, Silverlight and more. Note that for unit testing Silverlightthere is an open source Isolator add-on called SilverUnit.
The first 60 bloggers who will blog this text in their blog and tell us about it, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET dedicated blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.
Also 8 bloggers will get an additional 2 licenses (each) to give away to their readers / friends.
Go ahead, click the following link for more information on how to get your free license.
Thoughts on Unit Tests for Stored Procedures
So very recently I was approached by a team member to write some unit tests around a stored procedure that was being modified.I have never done any unit tests against for a Stored Proc so I was intrigued. I wasn’t really sure where I was going when I started but I opted to write a small console app in C# to proof it out.
For the sake of discussion, let’s say the stored procedure returns back a record-set with a single record containing five columns which describe time-zone information for a given US zip code and takes a single parameter, the zip code. I really couldn’t ask for a better test subject for a first pass, not too big, not too complicated.
My first inclination was to approach it like unit testing any other unit of code. So I figured I would need some variety of data store for my expected values and stored proc inputs. At this point it occurred to me, “Hey, I have a database full of inputs and expected results right here”, so I crafted a quick query to get my expected info. From that, I call the stored proc for each zip and verified the results. Worked like a champ. However, I was unaware the sp code refactoring had already been done on the database I was working against. It was around this point that I started getting a sinking feeling that something wasn’t right with the test. I attributed it to not being sure what to expect as this was a new testing scenario for me (typically the database developers are in charge of their development and testing of their code, while I can write SQL with the best of ‘em, a DBA I am not) and moved on.
Well ok, I have the behavior of the new code, the Actual results in testing terms. Now I can simply aim my program at the old database with the old code-base and get the expected results and modify my app to compare them. And then I discovered that the underlying data structure for the old code was different. The old way, the SP selects the five columns I need by joining three tables and then limiting on the passed in zip code. The new way, a nightly job is scheduled to populate a new “Time Zone” table and the SP simply selects all columns from the new table limiting by zip code.
So finally, it hits me… My test as it stands really is only testing that I get a result for every zip code I ask for and that it selected the same row that I got my expected result from. And maybe, that’s exactly what it should be testing, it does add some value… And yet it feels empty.
What I ended up doing was to retrieve the master list of zip codes from the old way’s table and ran both the new and old SP for each zip code and compared the result. This test felt better, the underlying data structures driving the stored proc could change and the test would be isolated and continue to work as long as the SP’s calling signature stayed the same.
The rub is, I could not have written my new test app without the new SP being developed. So what would I have been testing in it’s first iteration had I wrote tests for it at the time? I would have written my original test that would ultimately grab the expected data from the same database that the stored proc would.
What I should have done was adapt my initial test to work the same way with the old data and verified the stored proc returned the right data in my five columns. Then I should add a a test to verify the data in the new table matches the data from the old data structure. (This test typically would be the responsibility of the db job developers). Then I should modify my test to get it’s expected data from the new (and tested) structures and continue to verify the SP results to the data.
When unit testing code, you tend to have to “mock” out the data calls to control your tests, so from having to avoid all the database calls, it’s a “context-switch” to be requiring the database for everything. But the constant in both is testing the discrete parts from the bottom up. In retrospect, I could have done the test completely with SQL and suddenly the MS “Database Unit Test” makes a lot more sense.
–
Regards!
Typemock, my new best friend!
In particular, Typemock Isolator.
DISCLAIMER: I am in no way affiliated or receiving any compensation from the makers of Typemock. Simply a developer in the trenches loving this tool in his tool box. From thier website: http://www.typemock.com/index.php
| “Isolate any .NET dependencies to make unit testing easy” What does Isolator do?Typemock Isolator gives .NET developers the power to easily perform unit testing by making unit tests easy to write and automate.Isolator improves the bug-fix-time factor, and increases your code coverage. |
I’m not really going to review it, but it is an excellent product for use in writing unit tests. Plays 100% with NUnit. This is simply a no brainer, a tool you must have as a professional developer working with .NET.
If you are familiar with unit testing, then you have run into the "Mock” object. It looks and works just like the real thing, but it’s not, it’s a fake that does your bidding so you can control the outcomes of the tests to hit the proper scenarios for verification. And for small loosely coupled objects, this works with the added overhead of making the mock objects. But invariably you will end up with a data-bound object or a class sub-classed 3 levels deep and controlling the testing inputs gets harder and harder to control.
There are many development patterns out there that help to mitigate this “cost” such as factories with delegated constructors to allow snapping in of the data-provider, but these quickly become very complex beasts, and the codebase is just as large as the production code. Yes it works, yes it’s thorough, but is there a better way?
Yes! Why just today, I was creating some tests around a subsystem that essentially picks what will be shown to the user based on various rules. We are re-using the subsystem with another application and since the codebase is well set up and shared between like applications, with proper testing in place, we will be able to re-factor the code to be used in both spots with much higher confidence.
For one scenario, a random number between 0 and 99 is picked values less then 50 see A and the values greater then 50 see B. Well to right a test for this, you really need a consistent value returned from the random number generator. In my case, the random number was being returned from a private static little wrapper function around Random.GetNext() which I wil call GettRandomInt for namesake.
Typemock Isolater allowed me to intercept the call to GettRandomInt and force a return value of whatever I need for that test to be able to fully test my scenario. In a single line of code. That’s right 1 DAMN LINE OF CODE, I almost cried. Mind you I got lucky in that it was a static function so I never needed an instance, but at worse, 2 lines of code. Not too bad. And it was a private member as well. It has always been a source of frustration to only be able to test public functions, or to break ideal object model integrity for testing purposes alone. I mean of course quality is the clear choice here, but it isn’t free.
I was just very impressed with the product through a single day’s use. If you have ever “mocked autoquote” (and you know who you are (-: ) I guarantee, that’s right I said it, GUARANTEE, your satisfaction! I will be buying the personal edition for myself to use on my own projects, and for $89.00 that’s quite affordable.
They also have SharePoint isolator which I have not used, but have worked with SharePoint. And I can only imagine how this would be an essential tool.
Anyway, thank you Rob Witt for showing me the light. Amazing!
–
Regards!
