I've done a lot of heavy modification to some async code, and I've been tinkering with it long enough that I am in need of a second set of eyes.
In a unit test, I'm calling my async code, and then validating the values it should return. The object that ultimately performs the async operation is mocked.
The Unit Test:
public void GetCharactersAsync_ById_Test()
{
var charDictionary = TestHelper.GetCharactersIdDictionary(1);
var mockReq = new Mock<IRequester>();
mockReq.Setup(x => x.CreateGetRequestAsync<Dictionary<long, Character>>
(It.IsAny<string>())).ReturnsAsync(charDictionary);
var char1 = TestHelper.GetCharacter();
var api = GameObject.GetInstance(mockReq.Object);
var character = api.GetCharacterAsync(TestHelper.GetRegion(), (int)char.Id);
Assert.AreEqual(character.Result.Name, char1.Name);
}
GetCharacterAsync:
public async Task<Character> GetCharacterAsync(Region region, int charId)
{
var res = await requester.CreateGetRequestAsync<Task<Dictionary<long, Character>>>
(bld.BuildUrlForEndpoint("GetCharacter",
region, charId.ToString()));
var obj = res.Result.Values.FirstOrDefault();
return obj;
}
requester.CreateGetRequestAsync (though this should be mocked and not matter):
public async Task<T> CreateGetRequestAsync<T>(string urlString)
{
return await this.GetResultAsyncDeserialized<T>(new HttpRequestMessage(HttpMethod.Get, urlString));
}
and finally, GetResultAsyncDeserialized (though this is mocked and shouldn't matter):
protected async Task<T> GetResultAsyncDeserialized<T>(HttpRequestMessage request)
{
var result = string.Empty;
using (var response = await httpClient.GetAsync(request.RequestUri))
{
if (!response.IsSuccessStatusCode)
{
HandleRequestFailure(response.StatusCode);
}
using (var content = response.Content)
{
result = await content.ReadAsStringAsync();
}
}
return JsonConvert.DeserializeObject<T>(result);
}
I have next to zero experience with async, and this code is very similar to the old working code in structure (I moved a few things around, like the JsonConvert to the bottom layer when it used to be up top). The major changes, in fact, were all at the level that is being mocked, and shouldn't impact the unit test. The unit test is almost identical to the old one (removed some serialization/deserialization).
Exception is a Null Reference Exception on GetCharacterAsync line:
var obj = res.Result.Values.FirstOrDefault();