mocking a method to return different results

This week I was working on a piece of code that process batches and it had to be unit tested. Let’s think of this scenario. We have a service endpoint that creates a batch order (and a record in the database), and then for each item in that batch order it will create a product order (and again, a record in the database). If one of the product order fails, we need to revert the process, and delete all product orders together with the batch order.

Implementing it wasn’t a problem but when it came to unit testing the behaviour in the case when one product order fails, I had to think twice about it. Thankfully I discovered the SetupSequence method in the testing framework that I use (xUnit). What this method does is basically saying that when a method is called, I want the first value to be something, and the second value to be something else, in my case zero. I then decided to assert that not only the return would be zero (because the whole batch failed) but also that the method that reverts the transaction was called. Check out my implementation below;


[Fact]
public async void TheMethodImMocking_Returns_Zero_If_One_Of_The_Records_Not_Inserted()
{
// Arrange
Mock _mockDataLayerService = new Mock;
_mockDataLayerService.SetupSequence(x => x.ProcessIndividualOrder(It.IsAny())).ReturnsAsync(9999).ReturnsAsync(0);
// Act
var batchProcessingService = new BatchProcessingService(_mockDataLayerService.Object);
var result = batchProcessingService.ProcessBatchOrder()
// Assert
Assert.IsType(result);
Assert.Equal(0, result);
_mockDataLayerService.Verify(m => m.ReverseOrderProcessing(It.IsAny()), Times.Exactly(1));
}

The only catch when using the SetupSequence method is to know how many times the testable method will be called because if the return values, and the amount of calls do not match, an exception will be throw. Again, in my case I knew that I will be calling the method ProcessIndividualOrder twice so I setup the method to return a value twice.

I hope you’ll find this useful the same way I did, and happy unit testing 🙂

Bjorn

implementing a cascading dropdown list with MVC and Jquery

By definition (my own) a cascading dropdown list(s) is a set of dropdown list(s) dependent on their parent dropdown list. In this blog post we’ll see how this can be achieved in ASP.NET’s MVC pattern, with the help of some client-side scripting too. For simplicity I will be using the standard template that Visual Studio creates for you when you create a new project. Also, I uploaded the source code to this GitHub location.

All right so let’s say that we’re going to have three dropdown lists, and through these we will be able to drill down from continent, to countries, to cities. All the data in this project is hard coded but it can easily be retrieved from a database or some other source. So first thing we’ll do is update the Index method in the HomeController to make it look like the following;


public ActionResult Index()
{
continents = new List();
continents.Add(new SelectListItem { Text = "Select continent", Value = "0" });
continents.Add(new SelectListItem { Text = "Europe", Value = "1" });
continents.Add(new SelectListItem { Text = "North America", Value = "2" });
continents.Add(new SelectListItem { Text = "South America", Value = "3" });
ViewData["continents"] = continents;
countries = new List();
countries.Add(new SelectListItem { Text = "Select country", Value = "0" });
ViewData["countries"] = countries;
cities = new List();
cities.Add(new SelectListItem { Text = "Select city", Value = "0" });
ViewData["cities"] = cities;
return View();
}

So we created three lists of type SelectListItem and filling them with some data, and then passing them to our view using the ViewData. These lists can also be bound to a model and then pass the model to the view. I chose the ViewData option for simplicity. Within the view we need to create three dropdown lists and make a reference to the ViewData.


<div class="row">
<div class="col-md-4">
@Html.DropDownList("continents", ViewData["continents"] as List)
</div>
<div class="col-md-4">
@Html.DropDownList("countries", ViewData["countries"] as List)
</div>
<div class="col-md-4">
@Html.DropDownList("cities", ViewData["cities"] as List)
</div>
</div>

Now we got three dropdown lists with some data in them. For the next part we need to add some client-side scripting so we can load more data dynamically. Using Jquery we will make an AJAX call and get data according to what the user selected.


$("#continents").change(function () {
$("#countries").empty();
$.ajax({
type: 'POST',
url: '/Home/GetCountries',
dataType: 'json',
data: { selectedValue: $("#continents").val() },
success: function (areas) {
$.each(areas, function (i, area) {
$("#countries").append('' + area.Text + '');
});
},
error: function (ex) {
alert('Failed to retrieve countries.' + ex);
}
});
return false;
});
$("#countries").change(function () {
$("#cities").empty();
$.ajax({
type: 'POST',
url: '/Home/GetCities',
dataType: 'json',
data: { selectedValue: $("#countries").val() },
success: function (cases) {
$.each(cases, function (i, ucase) {
$("#cities").append('' + ucase.Text + '');
});
},
error: function (ex) {
alert('Failed to retrieve cities.' + ex);
}
});
return false;
});

Back to the HomeController we are going to create two entry points and do our logic in there.


public JsonResult GetCountries(string selectedValue)
{
countries = new List();
countries.Add(new SelectListItem { Text = "Select country", Value = "0" });
switch (selectedValue)
{
case "1":
countries.Add(new SelectListItem { Text = "United Kingdom", Value = "1" });
countries.Add(new SelectListItem { Text = "Italy", Value = "2" });
countries.Add(new SelectListItem { Text = "Greece", Value = "3" });
break;
case "2":
// more countries
break;
case "3":
// more countries
break;
}
return Json(new SelectList(countries, "Value", "Text"));
}
public JsonResult GetCities(string selectedValue)
{
cities = new List();
cities.Add(new SelectListItem { Text = "Select city", Value = "0" });
switch (selectedValue)
{
case "1":
cities.Add(new SelectListItem { Text = "Glasgow", Value = "1" });
cities.Add(new SelectListItem { Text = "London", Value = "2" });
cities.Add(new SelectListItem { Text = "Edinburgh", Value = "3" });
break;
case "2":
// more cities
break;
case "3":
// more cities
break;
case "4":
// more cities
break;
case "5":
// more cities
break;
// more cases
}
return Json(new SelectList(cities, "Value", "Text"));
}

And that should be it. Feel free to share your thoughts if you have any suggestions. Until the next post.

Bjorn

improving a website’s performance – part 2

A while back (i.e. more than a year ago! yeah I kept myself busy) I wrote the first part of this post, improving a website’s performance – part 1. A few tricks and tips which I’ve learnt over the years which improve a website’s performance, and in return giving the end user a better web experience. A better web experience increases and attracts traffic, and if your website generates money then that translates to profit *cha-ching*.

In the first part of this article the focus was on minification of resources, minimising HTTP requests and optimisation of images. In this post we will be looking at implementation of caching, server side improvements and useful performance tools.

Implement Caching

Latest web browsers can, and probably will, cache a website’s external files, such as CSS, JS and images. As a developer, enabling HTTP caching, will allow these files to be stored on the user’s machine after they are initially downloaded when the user visits the website for the first time. Once stored they will be used again whenever the user re-visits the website instead of re-downloading again. This is quite effective because it will improve the loading and response of the website. Think about it from this point of view, every time you’re hitting that “Back” button most of the data that is already downloaded will be fetched from the storage of your machine instead of getting packets of data from the web. One needs to be careful not to overload this feature though. Any content that features data or information that can change often must not be cached or else the user might end up reading expired information. This can be avoided by having shorter HTTP caching expiry dates to force the web browser to fetch the latest information. A good trick to make sure that the web browser is requesting the latest files from the server and not from the user’s storage is to change the file name.

Server Side Improvements

Improving a website’s performance does not necessarily mean tweaking some stuff from client side but also optimising processes from server side. Do review your code and don’t be afraid to make changes to your source code if a bottle neck is found. These optimisations will reflect on the website’s response and page load times. Tighten loops when possible by moving unnecessary logic. If a loop, that has a lot of iterations, has achieved the result after just a few iterations, then exit that loop and move on to the next process. Again, say a database connection, or even authentication calls, are being declared and populated inside the loop, then, do yourself a favour and make database calls outside of the loop to minimise the amount of calls being done. Other ways to write efficient code is to declare variable types if the data type is known. Avoid any unnecessary variable conversions and once the processing is complete set the variables which aren’t going to be used again to null, particularly if the variables’ type are of complex types and hold large amounts of data. Lastly, before writing the code, analyse the flows and consider implementing appropriate design. You would be surprised what a difference it makes in the long run to actually sit down and design the logic on a piece of paper before implementing it on your computer.

Performance Tools

To test the improvements or simply just to get an idea of the current rating of your website there are a few tools you can make use of. These tools analyse websites and grade features which are related to the website’s performance such as, minification of resources, the amount of HTTP request and image sizes being loaded, in other words the implementations that we have been discussing above and in the previous blog post. On top of that they check the website’s response time from different geographical locations and different web browsers, some of them also checking for mobile responsiveness. There is quite a selection of different tools you can use, some of them are online tools which test and produce their results via their website whereas others have to be downloaded and installed on your computer or web browser. Some of the most popular are Pingdom, KeyCDN, Website Speed Test and GTmetrix, the last two being completely free to use. Worth mentioning is that GTmetrix makes use of Yahoo’s YSlow and Google’s PageSpeed, two reliable tools that perform the same job however GTmetrix takes both results, compares them and produces the final rating.

Developing a website which looks nice and attractive is quite important if you would like to have a constant figure of visitors, because at the end of the day design is considered as a huge factor in web development. However, having said that, it is important to give the visitor a website that has a quick response time and an overall better user experience. When developing a website, it is important to keep in mind that the website should be running smoothly and implementing the features we have discussed would surely help to achieve this result.

reconciling your workspace in visual studio 2017 after a gated check-in

An interesting feature of Azure DevOps (formerly known as Team Foundation Server) is the so called gated check-in. What is a gated check-in? In simple terms, every time a developer commits some code a build machine will try to compile this shelveset before merging it into the current code repository. This feature is available to both Azure DevOps Service, which is Microsoft’s cloud service, and Azure DevOps Server, which is the exact same thing but on-premises.

As a developer you’d realise that the gated check-in feature is on because when you try to commit your changes you get prompted with a window similar to this.
1

We’re OK with it so we’re going to go ahead and click on Build Changes, and then after that we can notice a notification in the Team Explorer window.2

I like to click on the link where it says here. This opens a new window (see below) in Visual Studio. I tend to keep that open until the build agent is ready and the gated check-in is complete.
3.JPG

Clicking on the View Build Details link would open a new window in your internet browser and from there you can see all the processes of the build agent. A successful check-in is evident as the text and icons would turn green in both the internet browser and Visual Studio. For that same reason I like to keep the Build Request window open in Visual Studio as we get the option to reconcile workspace straight away, screenshot below. This action will basically remove all the new checked-in files from the Pending Changes section in Team Explorer.5

In case you closed the window after a successful check-in, or never really opened it, another way you can reconcile your workspace is from the Builds section in Team Explorer. Find your most recent successful build, right click and reconcile.
6

That should be it for today, till next post,
Bjorn

basic implementation of AWS SNS topic using c#

Cloud computing, or simply the cloud, has been quite the buzz word in recent years together with cloud service providers like Microsoft Azure, Google Cloud Platform and also – drum roll please – Amazon Web Services, also known as AWS. AWS has been around more than you think, since 2006 if we had to be exact, and in the developers vocabulary it’s really starting to become trendier.

One of the features AWS offers is Simple Notification Service (SNS). The idea behind it is a notification system to push new notifications to all users, or devices, subscribed to it. An SNS Topic is what users subscribe to and is the channel that will enable us to get in touch with them. In this blog post, however, we are going to assume that a topic has already been created and that we know the value of its ARN.

Now let’s focus on how we can send a request to that topic to trigger a new push notification. First thing we need to do is download and install two NuGet packages in our Visual Studio solution.

  • AWSSDK.Core
  • AWSSDK.SimpleNotificationService

Create a new C# class and paste the following code.


using Amazon;
using Amazon.Runtime;
using Amazon.SimpleNotificationService;
using Amazon.SimpleNotificationService.Model;
using System.Net;
class SnsEvents
{
const string AccessKey = "ABCDEFGHIJKLMNOPQRST";
const string SecretKey = "AbcdeFghiJKlmopqrS39VwXY0Za/1cdEF5I9aC";
const string SnsArn = "arn:aws:sns:eu-west-1:004673491943:TheNameOfTheSnsTopic";
static readonly RegionEndpoint Region = RegionEndpoint.EUWest1; //Same region as the ARN above
private static bool publishSnsRequest(string _message)
{
bool success = false;
AWSCredentials credentials;
credentials = new BasicAWSCredentials(AccessKey, SecretKey);
var client = new AmazonSimpleNotificationServiceClient(credentials, Region);
var request = new PublishRequest(SnsArn, _message);
var response = new PublishResponse();
response = client.Publish(request);
string requestId = response.ResponseMetadata.RequestId;
if (response.HttpStatusCode == HttpStatusCode.OK) {
success = true;
}
return success;
}
}

view raw

awssnstopic.cs

hosted with ❤ by GitHub

Analysing the code we can see that I declared four constant variables which will be used to connect to the SNS Topic. The values of these variables should be provided to you by the person maintaining the SNS. Also, notice the value of the region variable. Same region as specified in SNS’s ARN. Then, using the AWSCredentials object, we create a new credentials instance by supplying the access and secret key in the constructor’s parameters. A new AWS SNS client instance is created and the message that we want to send is published. Afterwards we check the response to make sure that our request was processed successfully.

A quick and straight forward post with a basic implementation of how to publish an SNS Topic from a .NET solution. There are much more options one can implement but this should be enough to get you started.

Until next post,
Bjorn