3 Rules for TDD

I couldn’t help but share this. There couldn’t be a better way to summarize the unwritten rules of TDD, than the one wrote by Uncle Bob in his famous book ‘Agile Principles, Patterns and Practices in C#”.

  • Don’t write any production code until you have written a failing unit test.
  • Don’t write more of a unit test than is sufficient to fail or fail to compile.
  • Don’t write any more production code than is sufficient to pass the failing test.

What it emphasises is when to switch between writing Unit Test and Production code, a key point, atleast according to me, for many times I see developers who try to think and build way too many test cases than what is actually needed. Honestly, yours truly too has been guilty of so called BDUF for Unit Test.

Uncle Bob, in formulating the 3 basic rules, emphasis that one needn’t write a unit test no more than when it fails or fails to compile, after which the developer proceeds to write the minimum code required to pass the test case. This short cycles would help the developer adopt the TDD approach in a better way.

Thanks Uncle Bob.

Mock RestClient.ExecuteAsync

RestSharp is not a stranger to developers, so is the usage. What this posts aims to explore is how to do Unit Test a method, involving a RestClient.ExecuteAsync call. To be more precise, the post explores how to mock the RestClient for the method.

Let’s consider the following code, taken from VSPostman, one of the side projects I am working on.

public async Task Get(string url)
{
if (string.IsNullOrWhiteSpace(url) || _parameterDictionary.Values.Contains(null)) throw new ArgumentNullException();

_restClient.BaseUrl = new Uri(url); // _restClient is an instance of RestClient
_restRequest.Method = Method.GET;
var _returnValue = new ResponseObject();
if(_parameterDictionary?.Count==0)
_restRequest.Parameters.AddRange(_parameterDictionary?.Select(x => new Parameter() {Name = x.Key, Value = x.Value }));
var tcs = new TaskCompletionSource();
var watch = Stopwatch.StartNew();
_restClient.ExecuteAsync(_restRequest, response =>
{
_returnValue.ContendType = response.ContentType;
_returnValue.ResponseString = response.Content;
_returnValue.StatusCode = response.StatusCode;
_returnValue.StatusDescription = response.StatusDescription;
_returnValue.ResponseTime = watch.Elapsed;
_returnValue.Length = response.ContentLength;
if (response.Headers != null)
_returnValue.Headers = response.Headers.ToDictionary(x => x.Name, y => y.Value as string);

tcs.SetResult(_returnValue);
});
return await tcs.Task;
}

As observed, the code raises a GET Request using the ReshSharp library. If I was using TDD and writing a Unit Test case for this method, how would I approach it ? How would I mock the RestSharp library calls ?

Of course, it is easy to understand that we need to create the mock object of IRestClient. But how do we create a response ? For this we attach a call back.

var expected = "response content";
var expectedBytes = Encoding.UTF8.GetBytes(expected);
Mock restClient = new Mock();
restClient.Setup(x => x.ExecuteAsync(
It.IsAny(),
It.IsAny<Action<IRestResponse, RestRequestAsyncHandle>>()))
.Callback<IRestRequest, Action<IRestResponse, RestRequestAsyncHandle>>((request, callback) =>
{
callback(new RestResponse { Content= expected }, null);
});
// act
var clientService = new ClientServiceUsingRestSharp(restClient.Object);
var actualResponse = await clientService.Get($"http://www.google.com");

That would be all you need. The callback would ensure you get the response from the mock object.