Skip to main content

Posts

Another Look at Unit Testing Umbraco Surface Controllers (Part 1)

When coming to work with Umbraco as an MVC developer one feature that is immediately familiar and comfortable to work with is surface controllers . Unfortunately, unlike standard MVC controllers, they aren't straightforward to test. In this blog post I'm going to look to start from scratch, uncover the issues and see what options we have to get around this. Failing test attempt Starting with a simple example taken from the Umbraco documentation , this surface controller action very simply handles a form post. The view model: public class CommentViewModel { [Required] public string Name { get; set; } [Required] public string Email { get; set; } [Required] [Display(Name = "Enter a comment")] public string Comment { get; set; } } The view and the form in a partial: @if (TempData["CustomMessage"] != null) { @TempData["CustomMessage"].ToString() } @Html.Partial("_CommentForm", new SurfaceCont...

Unit testing Umbraco IPublishedContent with Microsoft Fakes

Update: with more recent versions of Umbraco, there is a way introduced to me by Lars-Erik and documented in his blog post here that allows for testing IPublished content as attempted in this now fairly old post, without the user of MS Fakes. Given the the MS Fakes product still requires the Ultimate version of VS.Net I'd recommend using the technique he describes. I've recently been working on a package for Umbraco called Umbraco Mapper . It's intention is to support development of MVC based Umbraco applications by providing a simple means of mapping Umbraco content to custom view models. You can read more about it on the GitHub page . For a few weeks now I've on and off tackled a problem I've found with unit testing part of the functionality. Umbraco content is represented in the front-end of the application by an interface IPublishedContent . What I'm looking to do is to create an instance of IPublishedContent with some known properties, map it to a...

Async and await with external web resources

Async and await are two keywords that have been available in the C# for a while now. And so whilst probably a bit late to the party thought would share how I've used them for a recent feature, in case they are also new to others. They allow you to write async code much more easily than was previously possible, which should allow applications to scale better - particularly when there's a need to call out to slow running processes (e.g. external web services), or really anything that is "IO bound" (like a database call. So for example you could speed up a web request that requires two calls to two long running processes by running them in parallel on different threads and then waiting for both to return. If they both take 1 second your result can return in 1 second instead of 2. But even with just one long running process in the request, it's still useful, as whilst that process is running the thread serving the request is no longer blocked, and can return ...

Unit Testing Umbraco Surface Controllers

Unit testing Umbraco surface controllers isn't straightforward, due to issues with mocking or faking dependencies. There has been some discussion about it and there are some workarounds regarding using certain test base classes. But in general it's not an easy thing to do, at least at the moment. Another approach (or workaround) for this is to move the thing you are trying to test outside of the controller and into another class - that itself depends only on standard ASP.Net MVC. Test that instead, leaving your controller so simple that in itself there remains little value in testing it directly. As an example, I had this to test: [HttpPost] [ValidateAntiForgeryToken] public ActionResult SignUp(NewsletterSignUpModel model) { if (ModelState.IsValid) { // Model valid so sign-up email address var result = _newsletterSignUpService.SignUp(model.Email, model.FirstName, model.LastName); ...

JSON object versus array gotcha

Pulled a little of what's left of my hair out with this little gotcha looking at an issue with Umbraco. I was looking to add a small feature to allow you to re-order a list.  Umbraco (version 7) uses angularjs in the back-office.  Updating this controller and view code was very straightforward to add a couple of buttons to move the list items up and down.  However although I could see the order was properly being saved to the database, the retrieved list remained in the order that the items were created. Using the Chrome console network tab I could see that the JSON response was coming back from the server in the correct order: ... key":"items","value":{"10":"aaa","7":"bbb","8":"ccc"} ... However as soon as this materialised in code, the order was lost: ... key":"items","value":{"7":"bbb","8":"ccc","10":"aaa...