jones.busy

technical musings of a caffeine converter

NAVIGATION - SEARCH

Enabling external testing of .Net code with Fitnesse

Unit Tests not only offer an excellent entry point into writing good code with a TDD approach but can also offer a health check in the form of automatic regression testing for subsequent changes that may have had an unintended impact elsewhere in the system. But the tests are only valid for what they cover and often are only visible to the dev team. CI and automated builds often come with the tools to increase the visibility of these tests but still only offer a signature-level view of what is being tested.

Whilst searching for a way to elevate are tests, I was pointed in the direction of Fitnesse. A wiki based web tool that not only allows non-technical users to view tests but, to some extent, to specify and run them. It’s not a wrapper around existing unit tests, although I found I could use existing unit tests to help drive the ‘published’ versions. You will have to write some code to enable the tests to be run, but I found it to be a healthy exercise as the code you have to write forces you to consider what variables are of interest in each scenario and this can be done in collaboration with a tester, business analyst, or end user.

To get started, head over to the Fitnesse Download Page and download the fitness-standalone.jar file (yes, it does run on java, but is perfectly capable of running .net code)

Browse to the downloaded file’s location in a command prompt (runas Admin). I already had the standard port 80 in use so needed to specify a different port for install:

java -jar fitnesse-standalone.jar -p 8080

It’s worth browsing then to your local Fitnesse home page to ensure all installed correctly (http://localhost:90 in my case)

Next up you need to install a runner for your framework. The runner is akin to a unit test runner such as nunit and is responsible for loading in your .net dll and running the tests against it. There are two approaches with Finesse to testing – Slim and Fit, but the FitSharp runner manages both for .net testing so head over to its download page, grab the right version for your framework and unzip to an appropriate directory (in my case, c:\apps\fitSharp).

Next up is to set up a new suite ready for testing in your Fitnesse wiki. You can either create and then add a link to it or, as I prefer, add a link first then user the ‘Create New’ shortcut to do it for you. Click on the Edit menu to open up your home page ‘source code’.

You’ll see some odd table notation defined by lots of these: ||

To add a new link into the table, paste the following in (change the names to suit your needs but be wary which element refers to what component etc.):

| [[My Test Suite][.TestSuite]] | ''Test Suite Link'' |

Click Save, and you should see the following in your table:

image

If you click on the [?] you will be taking to a create page form. Just click Save in that form then you can head back to the home page and see that ‘My Test Suite’ has now become a proper link to that new page. Navigate to your TestSuite page (you can change these names to suit your needs), click Tools from the menu, then Properties.

Select Suite in the top box under Page type, then click Save Properties

image

Now head over to your VS solution. Let’s assume you have the following setup

image

So, FitnesseExample is a class library containing some dtos and view models (it would obviously contain a lot more). FitnesseExample.Tests is my test project (a plain class library with Rhino Mock and NUnit add through nuget but feel free to head down which ever testing route you prefer)

Given a view model as follows:

public class ExampleViewModel { public DateTime BookingDate { get; set; } public int TicketNumber { get; set; } public decimal TicketPrice { get; set; } public decimal TotalAmount { get { return TicketNumber * TicketPrice; } } public bool CanCommit () { return BookingDate > DateTime.Today && TicketNumber > 0; } }

I might create the following test:

[Test] public void CannotCommitIfBookingDateIsNotInTheFuture() { // arrange var vm = new ExampleViewModel(); // act vm.BookingDate = DateTime.Today; vm.TicketNumber = 1; // assert Assert.IsFalse(vm.CanCommit()); }

For the purpose of Fitnesse, this is where you would most likely deviate from the traditional route of unit testing. The first exercise would be to define the test:

CannotCommitIfBookingDateIsNotInTheFuture

Then, given the following criteria:

“Bookings cannot be committed unless the booking date is in the future and at least one ticket has been selected”

Work out which variables should impact this decision

TicketNumber & BookingDate

And also which variable needs to be checked:

CanCommit()

I use the term ‘variable’ in a very loose sense as this conversation would not involve the code itself so variable could refer to a method’s return value, a property etc.

The next step is to create a Decision Table – this is a column/row based format to defining the test and goes a bit like this:

|TESTNAME|

|VARIABLE_IN_A | VARIABLE_IN_B| .. | VARIABLE_OUT_A? | VARIABLE_OUT_B? | ..||

|TEST_INPUT_A | TEST_INPUT_B| .. | EXPECTED_OUTPUT_A | EXPECTED_OUTPUT_B | .. ||

It’s a bit convoluted – especially to a non technical mind so you can use Excel to set it out instead if preferred. In the case described above, I would have the following:

image

Note that the output variables are defined by a suffixed question mark. Back in Visual Studio, you now have to write a fixture class that will allow these variables to be set, read and acted upon. Here’s the fixture class for the above test:

namespace FitnessExample.Test.Fixtures { using System; using System.Globalization; using FitnesseExample.ViewModels; public class ValidationMustBePassedBeforeCommitting { private readonly string[] dateFormats = {"dd/MM/yy", "dd/MM/yyyy"}; private ExampleViewModel viewModel; public void Reset() { viewModel = new ExampleViewModel(); } public void SetBookingDate(string bookingDate) { var date = DateTime.ParseExact(bookingDate, dateFormats, null, DateTimeStyles.None); viewModel.BookingDate = date; } public void SetTicketNumber(int number) { viewModel.TicketNumber = number; } public int TicketNumber() { return viewModel.TicketNumber; } public bool CanCommit() { return viewModel.CanCommit(); } } }

UPDATE: I have since discovered that you can actually use Properties instead of the SetX() and X() approach for macthing so, in the example above, you could have a Property TicketNumber with a getter and setter that replaces the two methods.

It’s probably self-evident how it fits but here’s the breakdown:

1. The class is effectively the text from the first row, without spaces (keeping to Camel case convention)

2. Each input variable must have a matching void method prefixed with Set so Booking date needs SetBookingDate… etc.

3. For DateTimes, you can take in a string and convert based on one or more formats

4. For output variables, it’s simply a method that returns the expected value in Camel Case

You need to build your test project and copy all dlls from its output target dir to a test directory – let’s assume we are going with “C:\Fitnesse\” for now.

Head over to this directory and create a new xml file, “example.config.xml”. Paste in the following text:

<?xml version="1.0" encoding="utf-8" ?>
<suiteConfig>
  <ApplicationUnderTest>
    <AddAssembly>c:\fitnesse\FitnesseExample.Test.dll</AddAssembly>
    <AddNamespace>FitnesseExample.Test.Fixtures</AddNamespace>   
</ApplicationUnderTest>
  <Settings>
    <Runner>fitSharp.Slim.Service.Runner</Runner>
  </Settings>

</suiteConfig>

What this is telling the Fitnesse runner is what dll you are using to test, what sort of runner you are using, and any namespaces you are using to allow the runner to locate the fixture classes.

Back in your Fitnesse wiki, navigate to your Test Suite page, click Edit, and paste the following in:

!define TEST_SYSTEM {slim}
!define slim.timeout {60}
!define COMMAND_PATTERN {%m -c "c:\fitnesse\example.config.xml" %p}
!define TEST_RUNNER {c:\apps\fitSharp\Runner.exe}
!path c:\fitnesse\FitnessExample.Test.dll

This tells the page where to find your config file, where to locate the runner executable and the path to your test dll (I did wonder why we have to set the path here as well as add it to the config but if I left out the path, the tests did not run).

Underneath this test, paste the following:

[[Booking Tests][.TestSuite.BookingTests]]

Save the page and then click on the [?] next to the new link to create a page. Go back to your spreadsheet and select the columns and rows containing the test and copy them to your clipboard. Back on the test page, paste in the spreadsheet contents and then click the Spreadsheet to Finesse button:

imageimage

This converts the pasted text into a Decision Table. Click Save and you’ll see this now appear in your test page:

image

Now Click Tools –> Properties, and set the Page type to Test, and then click Save Properties

image

You should now see a Test button appear at the top op the page. Give it a click and see what happens. With any luck, it’ll be something similar to below – the important thing now is that the tests have run, regardless of whether they pass or not:

image

 

 

 

 

 

 

 

 

 

 

If you do not get this (and trust me, I spent a number of rounds before I got to this stage), check, check and check again on your paths, config files etc.

Ordering array of objects in Select Dropdown with Angular

As a newbie to angular and, in some sense, to javascript, when populating a select dropdown from an array of objects returned from my api, I fell into the trap of expecting the “| orderBy” filter to work as described. I’d already come a cropper with dynamically populated selects and trying to get the correct property to be shown so I probably should have been less surprised than I was.

Here’s the unordered select, populated from an array, ‘tenantTypes’ which itself is populated from an api call returning an array of a .net class, TenantType with the properties Id: long and Name: string.

<select ng-model="controller.registration.organisationType" ng-options="key as value.name for (key, value) in controller.tenantTypes" class="form-control"> <option value="">Organisation Type...</option> </select>

The ng-options statement took me some time to work out, but it worked as expected so I hope to be able to simply add the following in:

| orderBy:’name’

Not happening. The ng-options statement needed some jiggery-pokery to work with the object array and so does the sorting. After looking around, I came across this excellent filter created by Justin Klemm:

http://justinklemm.com/angularjs-filter-ordering-objects-ngrepeat/

Looks bang on the money so I grabbed it and added the following in:

| orderObjectBy:’name’

Still not happening: Once I’d ruled out my usual issues (reference the script, injecting it into the app module etc.), I started scratching my head. The only difference I could see was that this filter used the ng-repeat approach in its example. I knew I could have declared my select using <option ng-repeat… instead of the ng-options route but I had expected them to work the same under the bonnet. Well, if they do, then the ng-options does not work well with the custom filter as I finally managed to get my select ordering nicely by re-coding the select design to the following:

<select ng-model="controller.registration.organisationType" class="form-control"> <option value="" ng-selected="true">Organisation Type...</option> <option ng-repeat="type in controller.tenantTypes | orderObjectBy:'name'" value="{{type.id}}">{{type.name}} </option> </select>

Again, seasoned angular devs may be able to point out some glaring mistakes or assumptions I have made and please do, but just in case anyone else has tried or is trying the same approach, this might at least save them a couple of hours of head scratching Smile

Extending Angular $http service

Recently, I’ve been working with AngularJs, developing an Azure targeted application with an Entity Framework (Code First) backend, Web Api v2.0 middle tier and an AngularJs front-end. I like AngularJS for a number of reasons, one of which is that, as a .Net, WPF developer for most of my time, having so many different options and approaches to consider with client-side web development, having a framework that minimises those options into one core approach is beneficial to me. I completely understand that this same reason could be seen as a negative and I am well aware of the impending re-write of Angular due this year but to move from the safety net of a strongly typed .net background to the javascript playground, AngularJS feels a little like I’ve got some stabilisers on my dev bike Smile

Using the $http service over the weekend, I stumbled across a couple of issues:

1. Calling a web api method with a simple string parameter:

public async Task<IHttpActionResult> PostRole([FromBody]string roleName)

The issue is that by sending the string across as a variable causes some misinterpretation of as it as a json literal so instead of the value finding its way to the web api method, you get a null object instead. So, instead of calling the following:

return $http.post(serviceBase + 'api/admin/roles', roleName);

You need to do this:

return $http.post(serviceBase + 'api/admin/roles', "'" + roleName + "'");

2. Calling a ‘get’ method from within IE:

public async Task<IHttpActionResult> Get()

For some unknown reason, no matter how hard I tried to stop this from caching when testing in IE, I had no luck. In the end, the only approach that worked for me was to randomise the request as follows:

return $http.get(serviceBase + 'api/admin/roles?rnd=' + new Date().getTime());

It’s not very pretty is it? Firstly, I must asking anyone reading that has any suggestions or comments about what I’ve done or the issues I have faced, please do get in touch as it is perfectly feasible I have completely crossed my wires with this and there is another approach I should have taken. But for now, these are the issues I hit, Googled, and then put in some workarounds.

Now, having found a workaround, I realised that these sorts of calls could be a regular occurrence and so I don’t want to have to remember to apply these fixes each time. My first thought was to see whether I could extend the $http service to wrap this functionality in a neat bundle for me. Coming from C# extension methods i looked at the following options:

1. prototyping

2. behaviours

3. providers

I’ve heard about most of these approaches but never seen any in practice. I really wanted to stick to passing in $http and just being able to either handle or extend the functionality to handle these requirements but could not get this to work with my limited javascript knowledge. In the end, I create a new service, extendedHttpService, which is actually a factory class that returns an extended version of the $http service:

(function (ng, app) { "use strict"; app.factory('extendedHttpService', ['$http', function($http) { var forceGet = function(url) { return $http.get(url + "?rnd=" + new Date().getTime()); }; var postString = function(url, str) { return $http.post(url, "\"" + str + "\""); }; $http['forceGet'] = forceGet; $http['postString'] = postString; return $http; } ]); })(angular, app);

Allowing me to then call the extended functions as follows:

(function (ng, app) { "use strict"; app.service('rolesService', ['extendedHttpService', 'appSettings', function (extendedHttpService, appSettings) { var serviceBase = appSettings.apiServiceBaseUri; this.getAllRoles = function () { return extendedHttpService.forceGet(serviceBase + "api/admin/roles/"); }; this.createRole = function (roleName) { return extendedHttpService.postString(serviceBase + 'api/admin/roles', roleName); }; this.updateRole = function (role) { return extendedHttpService.put(serviceBase + 'api/admin/roles', role); }; }]); })(angular, app);

This is much neater, but I’d love to hear on other approaches that I could have used in this scenario.

Separating Knockout Viewmodel from View

As mentioned in a previous post, I’m becoming a big fan of Knockout. I don’t favour MVVM over MVC per se, simply like the idea of being able to manipulate, and react to the model changing on the client side without the need for a return server trip every time.

Whilst it is perfectly normal for a Knockout view model to be declared inside the cshtml View to which it is bound, I have found that very quickly, the script can become quite bulky and difficult to maintain.

Take for instance the following script inside a View of mine:

   1: @section Scripts

   2: {

   3:     <script type="text/javascript">

   4:         /// <reference path="../jquery-1.9.1.js" />

   5:         /// <reference path="../knockout-2.2.1.js" />

   6:         /// <reference path="knockout.extensions.js" />

   7:         /// <reference path="../knockout.mapping-latest.js" />

   8:         /// <reference path="../jquery-ui-1.10.2.js" />

   9:         (function () {

  10:  

  11:             var viewModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));

  12:             viewModel.currentView = ko.observable('company');

  13:             viewModel.editMode = ko.observable(false);

  14:             viewModel.editMode.subscribe(detailsRendering.toggleModelEdit);

  15:  

  16:             var btnActiveClass = 'btn-success';

  17:  

  18:             var manageSelection = function () {

  19:                 removeSelection();

  20:                 viewModel.currentView($(this).data("view-id"));

  21:                 addSelection($(this));

  22:             };

  23:  

  24:             var addSelection = function (element) {

  25:                 element.addClass("btn-primary");

  26:             };

  27:  

  28:             var removeSelection = function () {

  29:                 $(".detailsSelector").removeClass("btn-primary");                

  30:             };

  31:  

  32:             var toggleModelEdit = function (edit) {

  33:                 if (edit) {

  34:                     $("#lockModelBtn").removeClass(btnActiveClass);

  35:                     $("#unlockModelBtn").addClass(btnActiveClass);

  36:                 } else {

  37:                     $("#unlockModelBtn").removeClass(btnActiveClass);

  38:                     $("#lockModelBtn").addClass(btnActiveClass); 

  39:                 }

  40:             };

  41:  

  42:             $(".detailsSelector").on('click', manageSelection);

  43:             $("#lockModelBtn").on('click', function () { viewModel.editMode(false); });

  44:             $("#unlockModelBtn").on('click', function () { viewModel.editMode(true); });

  45:  

  46:             addSelection($("#companyDetailsSelector"));            

  47:  

  48:             toggleModelEdit(false);

  49:  

  50:             ko.applyBindings(viewModel);

  51:         })();

  52:     </script>   

  53: } 

It’s not very complicated but already I am finding it a little fiddly to follow. And, I’m not yet finished with the code, so it’ll only get bigger. I could separate out the areas responsible for initialising the view model from those responsible for reacting to user interaction with multiple script tags but a) that would add extra js code and b) I have a lot of overlap between the two areas of responsibility so scope is an important issue.

What I opted to go with is the Revealing Module Pattern (RMP) that provides a nice separation of concern in simplistic fashion. I created three RMP functions:

1. Initialise View Model

2. Initialise View

3. Handle User Interaction with the View

The resulting script is as follows:

   1: /// <reference path="../jquery-1.9.1.js" />

   2: /// <reference path="../knockout-2.2.1.js" />

   3: /// <reference path="knockout.extensions.js" />

   4: /// <reference path="../knockout.mapping-latest.js" />

   5: /// <reference path="../jquery-ui-1.10.2.js" />

   6: var details = function () {

   7:     

   8:     var initialiseViewModel = function (data) {

   9:         var viewModel = data;

  10:         viewModel.currentView = ko.observable('company');

  11:         viewModel.editMode = ko.observable(false);

  12:         viewModel.editMode.subscribe(detailsRendering.toggleModelEdit);

  13:  

  14:         ko.applyBindings(viewModel);

  15:  

  16:         return viewModel;

  17:     }

  18:  

  19:     return {

  20:         initialiseViewModel: initialiseViewModel

  21:     };

  22: }();

  23:  

  24: var detailsView = function () {

  25:  

  26:     wireEvents = function (vm) {

  27:         $(".detailsSelector").on('click', function () { detailsRendering.manageSelection(vm, $(this)); });

  28:         $("#lockModelBtn").on('click', function () { vm.editMode(false); });

  29:         $("#unlockModelBtn").on('click', function () { vm.editMode(true); });

  30:     },

  31:  

  32:     initialiseView = function (vm) {

  33:  

  34:         wireEvents(vm);

  35:         detailsRendering.manageSelection(vm, $("#companyDetailsSelector"));

  36:         detailsRendering.toggleModelEdit(false);

  37:     }

  38:  

  39:     return {

  40:         initialiseView: initialiseView

  41:     };

  42: }();

  43:  

  44: var detailsRendering = function () {

  45:  

  46:     var btnActiveClass = 'btn-success',

  47:     btnPrimaryClass = 'btn-primary',

  48:  

  49:     addSelection = function (element) {

  50:         element.addClass(btnPrimaryClass);

  51:     },

  52:  

  53:     removeSelection = function () {

  54:         $(".detailsSelector").removeClass(btnPrimaryClass);

  55:     }

  56:  

  57:     toggleModelEdit = function (edit) {

  58:         if (edit) {

  59:             $("#lockModelBtn").removeClass(btnActiveClass);

  60:             $("#unlockModelBtn").addClass(btnActiveClass);

  61:         } else {

  62:             $("#unlockModelBtn").removeClass(btnActiveClass);

  63:             $("#lockModelBtn").addClass(btnActiveClass);

  64:         }

  65:     },

  66:     manageSelection = function (viewModel, element) {

  67:          removeSelection();

  68:          viewModel.currentView(element.data("view-id"));

  69:          addSelection(element);

  70:      }

  71:  

  72:     return {        

  73:         toggleModelEdit: toggleModelEdit,

  74:         manageSelection: manageSelection

  75:     };

  76: }();

The first module, “details” (named after the view), providers a function for setting up the view model and returning. It does nothing else and knows of nothing else. The only dependency it has is on the initial input of the model which has come from the server.

The second module, “detailsView”, expects the view model and sets up the components in view from wiring the click events, to setting up the default view by calling into the third module, “detailsRendering”, which again expects the view model as an input and provides the functionality for manipulating the view based on either the user’s input or manually in the case of the detailsView initial setup. These three modules are in the same js file, but could quite easily be separated out, in which case, I’d be wise to use something like require to handle dependencies and also minimise the load.

To get the ball rolling, the html embedded script now looks like this:

   1: @section Scripts

   2: {

   3:     <script src="~/scripts/app/page.details.js"></script>   

   4:     

   5:     <script type="text/javascript">

   6:         (function () {

   7:             var viewModel = details.initialiseViewModel(ko.mapping.fromJS(@Html.Raw(Json.Encode(Model))));

   8:             detailsView.initialiseView(viewModel);

   9:         })();

  10:     </script>    

  11: }

Rather than returning the view model from the initial function, I could have called the initialiseView method from within but this way, I have the option of making further calls if needs be without the need to chain. Having spent most of my time in C# and Xaml, I’d love to hear from html and javascript guys on what their preferred approach to client side MVVM is.

Adding Unique Constraint to column using EF Code First

First of all, it has been a very long time since this blog was last active. About 2 and a half years in all. That’s also the same age as my daughter. Spare time? What is that, exactly?!

Anyway, I have recently been working on my own project and decided to dive deeper into the Code First approach of Entity Framework. In particular, I do like the idea of being able to design your entities in an OO fashion and have that matched in the Database. This is more appealing when you can use the Fluent API to manage relational rules such as required properties without contaminating the core entity itself. I like it a lot.

However, I came a cropper the other day when I decided I wanted to add a Unique constraint on to the Name property of my Company table. Not an unusual request, so I was a little baffled as to why I did not have the following as an operation in Fluent API:

   1: public CompanyConfiguration()

   2: {

   3:     Property(x => x.Name).IsUnique();

   4:     Property(x => x.Name).IsRequired();

   5:     Property(x => x.Name).HasMaxLength(256);

   6: }

 

BTW, this is part of a Configuration class based on EntityTypeConfiguration<T>. The line that did not compile is the IsUnique() one.

Digging around on the web, I noticed that such functionality was planned for EF 5.0 but got pulled. My suspicions lie around the fact that this is a table constraint, rather than a field attribute so it would have more of an impact on how it is used. Either way, I had a look at how people worked around this and a common approach was to execute an “ALTER TABLE…..” command somewhere sensible such as the Database Initializer class. This was the approach I decided to take myself but I wanted to do so in a way that allowed a more DRY approach for any property in any class I wanted to set a Unique constraint on

The result was the following method in my DbContext Initializer class:

   1: private void AddUniqueConstraint<T>(Expression<Func<object>> expression) 

   2:             where T : DataEntityBase

   3: {

   4:    var columnName = String.Empty;

   5:  

   6:    if (expression.Body is MemberExpression)

   7:    {

   8:        columnName = ((MemberExpression)(expression.Body)).Member.Name;

   9:    }

  10:    else if (expression.Body is UnaryExpression)

  11:    {

  12:        columnName = ((MemberExpression)(((UnaryExpression)(expression.Body)).Operand)).Member.Name;                

  13:    }

  14:  

  15:    var script = "ALTER TABLE {0} ADD CONSTRAINT uc_{1} UNIQUE ({1})".FormatWith(Pluralizer.Pluralize(typeof(T).Name), columnName);

  16:    _context.Database.ExecuteSqlCommand(script);

  17: }

It’s not entirely tidy – you have to create an instance of the class in order to pass in the property name so perhaps someone out there can recommend a different approach – maybe using reflection?

In any case, it’s doing a job for me. For reference, GlobalContext is my DbContext class, DataEntityBase is an abstract class that holds common properties for classes to be added to the Database and FormatWith is simply a String extension method I use in preference to String.Format(“…”) etc.

note: my original approach to resolving the property name was flawed in so much as it would throw an exception if the expression.Body was a UnaryExpression, not a MemberExpression. I have since rectified this and updated the post accordingly.