Building a web service with Node.js in Visual Studio Part 10: testing GET actions

Introduction

In the previous post of this series we tested the insertion of new customers through a simple C# console application.

In this post we’ll extend our demo C# tester application to test GET actions.

We’ll be working on our demo application CustomerOrdersApi so have it ready in Visual Studio and let’s get to it.

Testing GET

We created our domain objects in the previous post with JSON-related attributes: Customer and Order. We’ll now use these objects to test the GET operations of the web service. We created a class called ApiTesterService to run the tests for us. Open that file and add the following two methods:

public List<Customer> GetAllCustomers()
{
	HttpRequestMessage getRequest = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost:1337/customers"));
	getRequest.Headers.ExpectContinue = false;
	HttpClient httpClient = new HttpClient();
	httpClient.Timeout = new TimeSpan(0, 10, 0);
	Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(getRequest,
			HttpCompletionOption.ResponseContentRead, CancellationToken.None);
	HttpResponseMessage httpResponse = httpRequest.Result;
	HttpStatusCode statusCode = httpResponse.StatusCode;
	HttpContent responseContent = httpResponse.Content;
	if (responseContent != null)
	{
		Task<String> stringContentsTask = responseContent.ReadAsStringAsync();
		String stringContents = stringContentsTask.Result;
		List<Customer> allCustomers = JsonConvert.DeserializeObject<List<Customer>>(stringContents);
		return allCustomers;
	}

	throw new IOException("Exception when retrieving all customers");
}

public Customer GetSpecificCustomer(String id)
{
	HttpRequestMessage getRequest = new HttpRequestMessage(HttpMethod.Get, new Uri("http://localhost:1337/customers/" + id));
	getRequest.Headers.ExpectContinue = false;
	HttpClient httpClient = new HttpClient();
	httpClient.Timeout = new TimeSpan(0, 10, 0);
	Task<HttpResponseMessage> httpRequest = httpClient.SendAsync(getRequest,
			HttpCompletionOption.ResponseContentRead, CancellationToken.None);
	HttpResponseMessage httpResponse = httpRequest.Result;
	HttpStatusCode statusCode = httpResponse.StatusCode;
	HttpContent responseContent = httpResponse.Content;
	if (responseContent != null)
	{
		Task<String> stringContentsTask = responseContent.ReadAsStringAsync();
		String stringContents = stringContentsTask.Result;
		List<Customer> customers = JsonConvert.DeserializeObject<List<Customer>>(stringContents);
		return customers[0];
	}
	throw new IOException("Exception when retrieving single customer.");
}

I know this is a lot of duplication but this will suffice for demo purposes. GetAllCustomers(), like the name implies will retrieve all customers from the Node.js web service. GetSpecificCustomer(string id) will retrieve a single customer by its ID. You may be wondering why we get a list of customers in GetSpecificCustomer. MongoDb will return all matching documents in an array. So if there’s only one matching document then it will be put into an array as well. Therefore we extract the first and only element from that list and return it from the function. We saw something similar in the previous post where we tested the POST operation: MongoDb responded with an array which included a single element, i.e. the one that was inserted.

So we’re testing the two GET endpoints of our Node.js service:

app.get("/customers" ...
app.get("/customers/:id" ...

We can call these methods from Program.cs through the following helper method:

private static void TestCustomerRetrieval()
{
	Console.WriteLine("Testing item retrieval.");
	Console.WriteLine("Retrieving all customers:");
	Console.WriteLine("=================================");
	ApiTesterService service = new ApiTesterService();
	try
	{
		List<Customer> allCustomers = service.GetAllCustomers();
		Console.WriteLine("Found {0} customers: ", allCustomers.Count);
		foreach (Customer c in allCustomers)
		{
			Console.WriteLine("Id: {0}, name: {1}, has {2} order(s).", c.Id, c.Name, c.Orders.Count);
			foreach (Order o in c.Orders)
			{
				Console.WriteLine("Item: {0}, price: {1}, quantity: {2}", o.Item, o.Price, o.Quantity);
			}
		}

		Console.WriteLine();
		Customer customer = SelectRandom(allCustomers);
		Console.WriteLine("Retrieving single customer with ID {0}.", customer.Id);
		Customer getById = service.GetSpecificCustomer(customer.Id);

		Console.WriteLine("Id: {0}, name: {1}, has {2} order(s).", getById.Id, getById.Name, getById.Orders.Count);
		foreach (Order o in getById.Orders)
		{
			Console.WriteLine("Item: {0}, prigetByIde: {1}, quantity: {2}", o.Item, o.Price, o.Quantity);
		}
	}
	catch (Exception ex)
	{
		Console.WriteLine("Exception caught while testing GET: {0}", ex.Message);
	}

	Console.WriteLine("=================================");
	Console.WriteLine("End of item retrieval tests.");
}

The above method first retrieves all customers from the service and prints some information about them: their IDs and orders. Then a customer is selected at random and we test the “get by id” functionality. Here’s the SelectRandom method:

private static Customer SelectRandom(List<Customer> allCustomers)
{
	Random random = new Random();
	int i = random.Next(0, allCustomers.Count);
	return allCustomers[i];
}

Call TestCustomerRetrieval from Main:

static void Main(string[] args)
{			
	TestCustomerUp();

	Console.WriteLine("Main done...");
	Console.ReadKey();
}

Start the application with F5. As the Node.js project is set as the startup project you’ll see it start in a browser as before. Do the following to start the tester console app:

  • Right-click it in Solution Explorer
  • Select Debug
  • Select Start new instance

If all goes well then you’ll see some customer information in the command window depending on what you’ve entered into the customers collection before:

testing GET through tester application

The web service responds with JSON similar to the following in the case of “get all customers”:

[{"_id":"544cbaf1da8014d9145c85e7","name":"Donald Duck","orders":[]},{"_id":"544cb61fda8014d9145c85e6","name":"Great customer","orders":[{"item":"Book","quantity":2,"itemPrice":10},{"item":"Car","quantity":1,"itemPrice":2000}]},{"_id":"546b56f1b8fd6abc122cc8ff","name":"hello","orders":[]}]

…and here’s the raw response body of “get by id”:

[{"_id":"544cbaf1da8014d9145c85e7","name":"Donald Duck","orders":[]}]

Note that this JSON is also an array even so we’ll need to read the first element from the customers list in the GetSpecificCustomer function as noted above.

In the next post, which will finish this series, we’ll take a look at updates and deletions, i.e. the PUT and DELETE operations.

View all posts related to Node here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

iReadable { }

.NET Tips & Tricks

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Ricos Blog zu Softwaredesign- und architektur

Ideen und Gedanken rund um Softwaredesign und -architektur, Domain-Driven Design, C# und Windows Azure

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: