2

I am looking for guidance on setting up the synchronization context for a complex integration test where the SUT includes async ASP.NET actions.

I have a mock HttpContext and can exercise synchronous action methods. But async actions often fail with HttpContext.Current null. From reading around, I think I need to call SynchronizationContext.SetSynchronizationContext in order to get the HttpContext.Current to be "moved" from one thread to another as the async operations proceed.

I've tried:

  • A simple TestSynchronizationContext similar to this - still fails with null HttpContext.Current
  • Instantiate an AspNetSynchronizationContext using reflection - not managed yet as class and dependencies are internal which makes this really difficult

Any suggestions?

1 Answer 1

1

You should be able to use pretty much any synchronization context that calls all code on the main test thread. That way your artificial HttpContext.Current will be visible to all code.

The way this works is that there is an internal Queue<Action>. The initial action is run and can queue additional stuff. The queue is drained until all outstanding work has completed. SynchronizationContext has a notion of outstanding operations which is essentially an integer counter.

The NitoAsync project is a popular async extension library. It contains such a synchronization context (I don't have the class name handy; grep for SynchronizationContext).

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks usr. This looks promising. As I'm running an acceptance test within the SpecFlow framework I guess I'll have to ensure the "queue is drained" at the end of each async test step before proceeding to the next.
I've looked through Nito.AsyncEx but cannot find a suitable SynchronizationContext. I used this to "grep" for it: github.com/StephenCleary/AsyncEx/find/v4
@MrBlueSky I think I found it. It's called AsyncContext. github.com/StephenCleary/AsyncEx/wiki/AsyncContext
Thanks, @usr. I tried this, and another similar solution from github.com/antiufo/Shaman.SingleThreadSynchronizationContext too. For whatever reason, I still experienced intermittent null HttpContext.Current.
I've resolved the situation in my case by abstracting out the access to the HttpContext.Current behind an IHttpContextFactory and referencing the captured mock context (nuget.org/packages/HttpSimulator) from my HttpContextFactory. (So I had to make production code changes which I didn't really want to have to do.)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.