I am writing automated tests for a large application.
Some of these tests could easily be async
methods, as they make use of an HttpClient
, which offers only async
methods for issuing requests.
Some crucial aspects of the application to test are the following:
- It is a huge ASP.NET application (though the code is not running within an ASP.NET context when executed through unit tests).
- In its core, it relies heavily on static objects that cache context information (e.g. the entire permission scheme of the active user) per thread.
Now, my problem is that when using await
in an async
method, the continuation might happen in a different thread than before (as described in answers such as this or this). Obviously, the other thread doesn't have the aforementioned cached context information and I'm immediately drowning in exceptions as soon as I invoke anything.
Now, if I use GetAwaiter().GetResult()
(as suggested here) instead of await
on the HTTP calls and make my test methods synchronous, everything appears to work fine for my test cases.
Will this solution reliably ensure my entire test case will run on the same thread? Or do I have to pick one of the seemingly more complex solutions, such as implementing a custom synchronization context?
EDIT: To be clear: Changing the architecture of the application core itself, as questionable as its design may or may not be, is not an option.
To be clear no. 2: The only async
methods I would like to call are the ones on HttpClient
for sending HTTP requests. Our own code does not contain any async
methods (possibly, for the reasons described above).
EDIT2: Here's a simplified version of my test method, to give an idea of what kinds of calls are in there:
[Test]
public async Task TestWriteAsync()
{
MyAppLogic.Initialize(TestConstants.TestUserId);
MyAppLogic.CleanUp();
using (var client = new HttpClient())
{
var content = ... // my input data
var response = await client.PostAsync("http://my.web.app.com/application/write", content);
Assert.IsTrue(response.IsSuccessStatusCode);
Assert.AreEqual(..., MyAppLogic.GetValue());
MyAppLogic.CleanUp();
}
}
Tentative rewrite that appears to work:
[Test]
public void TestWrite()
{
MyAppLogic.Initialize(TestConstants.TestUserId);
MyAppLogic.CleanUp();
using (var client = new HttpClient())
{
var content = ... // my input data
var response = client.PostAsync("http://my.web.app.com/application/write", content).GetAwaiter().GetResult();
Assert.IsTrue(response.IsSuccessStatusCode);
Assert.AreEqual(..., MyAppLogic.GetValue());
MyAppLogic.CleanUp();
}
}