Continuing from my last post. Documenting the Service class unit tests remains. A quick look at the source code shows there are three service classes but, regrettably only one of them can be tested. The Message service requires a user response that I have yet to figure out how to do programmatically for the unit test. I am pretty sure I can do that in a UI test which is still on my “to-do” list. The other service class which I can’t test is the MicrosoftAuthService Class. It appears the Interface for the PublicClientApplication (IPublicClientApplication in the Microsoft.Identity.Client library) still contains “obsolete” methods which throw errors (not warnings) in my compiler. If they were warnings I could do it but, the errors prevent any kind of fake (that I know of) for this interface. Hopefully, A future version of the Interface will remove the obsolete methods. So the only Service I can test at the time of this writing is the WineStore service.
As in the previous post I have written the tests (for this article) against the minimal version of the application I used in the post …You Get the Horns Part 2. There are more tests in the “full-featured” project, This application only uses one method in the WineStore service and that is “GetCellarsAsync”. Its code follows:
public async Task<ObservableCollection<CellarSummaryModel>> GetCellarsAsync(string BearerTokenString = null, HttpRequestMessage HttpMessage = null)
{
var listofCellars = new ObservableCollection<CellarSummaryModel>();
Token = BearerTokenString??SecureStorage.GetAsync("token").Result;
HttpMessage = HttpMessage?? new HttpRequestMessage(HttpMethod.Get, CellarSummaryUri);
HttpMessage.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", Token);
var response = await _client.SendAsync(HttpMessage);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
listofCellars = JsonConvert.DeserializeObject<ObservableCollection<CellarSummaryModel>>(content);
}
else
{
throw new Exception($"Request did not return a Success Status Code code is: {response.StatusCode}");
}
return listofCellars;
}
There are only two ways to exit this method: Successfully and by Exception. To achieve this we need a Fake HttpMessageHandler object so that the http response message can be “set up”. My search of the internet to find such an object led me to A GitHub post by Benjamin Hyshell. The Fake documented in this post allows control of the http requests’ response used by the WineStore Method allowing the return of successful data or a response which is not “OK” which will cause the WineStore to throw an exception. With that said, the unit tests end up being:
[Test]
public async Task GetCellarsAsync_ReturnsValidResponse()
{
var fakeResponse = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(TestValues.CellarSummaryModelListJson, Encoding.UTF8, "application/json")
};
var fakeHandler = new FakeHttpMessageHandler(fakeResponse);
var fakeHttpClient = new HttpClient(fakeHandler) {BaseAddress = new Uri("http://localhost")};
SystemUnderTest = new AuthXamSam.Services.WineStore(fakeHttpClient);
var result = await Task.FromResult(SystemUnderTest.GetCellarsAsync("foobarToken"));
var expectedResult =
JsonConvert.DeserializeObject<ObservableCollection<CellarSummaryModel>>(TestValues
.CellarSummaryModelListJson);
Assert.AreEqual(expectedResult.Count, result.Result.Count);
Assert.AreEqual(expectedResult[0].CellarId.PartitionKey, result.Result[0].CellarId.PartitionKey);
Assert.AreEqual(expectedResult[0].CellarId.RowKey, result.Result[0].CellarId.RowKey);
Assert.AreEqual(expectedResult[0].CellarId.TimeStamp, result.Result[0].CellarId.TimeStamp);
Assert.AreEqual(expectedResult[0].Capacity, result.Result[0].Capacity);
Assert.AreEqual(expectedResult[0].Description, result.Result[0].Description);
Assert.AreEqual(expectedResult[0].Value, result.Result[0].Value);
}
[Test]
public void GetCellarsAsync_ThrowsExceptionWhenResponseIsNotSuccess()
{
var fakeResponse = new HttpResponseMessage
{
StatusCode = HttpStatusCode.ServiceUnavailable,
};
var fakeHandler = new FakeHttpMessageHandler(fakeResponse);
var fakeHttpClient = new HttpClient(fakeHandler) {BaseAddress = new Uri("http://localhost")};
SystemUnderTest = new AuthXamSam.Services.WineStore(fakeHttpClient);
Assert.That(async ()=> await SystemUnderTest.GetCellarsAsync("foobarToken"), Throws.Exception);
}
All of the Unit tests are now written so, I will be turning my attention to a “Bulk Loader” for a cellar collection.
As always comments are always appreciated.