0

I have Web Api controller Action method I am trying to unit test. I have one custom filter which runs before that action controller.

I have question regarding HttpContext.Current.User.Identity.Name that I am using inside my custom action filter.

It works nicely when I send my http post request from web client.

But, when I send http post request from my unit test than HttpContext.Current always complain for null

Don't understand where and what is wrong. Anybody can please explain it?

Please note that I have seen answers at here but not sure where I need to add that code in my case.

Community
  • 1
  • 1
immirza
  • 5,493
  • 6
  • 42
  • 71

2 Answers2

1

Unit testing is not the same as calling your api through a web client.

When you are using a web client, you api is running in the context of you web server (IIS, for example) and the web server will provide the system with che "current" HttpContext.

If you call you code plain and simple from a unit test method you're not running in the context of a web server, but you're calling it simply as a method of a class. Obviously you can do it, but you need to "mock" (of fake, if you want) the current HttpContext to simulate you're running in a real web server.

Check this SO answer for the details on how to do it.

BTW, this is not the case when you run integration tests (means calling the real API throught a web client and just check the input-output results): in that case you are running your real code in a real context and everything will work fine.

Luca Ghersi
  • 2,956
  • 18
  • 28
0

HttpContext.Current is not set in a self hosted scenario like in your test.

You can however create a wrapper around HttpContext.Current and populate it before you run your test. Like this:

public static class CurrentHttpContext
{
    public static Func<HttpContextBase> Instance = () => new HttpContextWrapper(HttpContext.Current);
}

And then somewhere in your test where you set up your HttpSelfHostServer, you populate the CurrentHttpContext.Instance. For example with FakeItEasy (https://github.com/FakeItEasy/FakeItEasy):

var context = A.Fake<HttpContextBase>();
CurrentHttpContext.Instance = () => context;

Then you can access CurrentHttpContext.Instance instead of HttpContext.Current in your filters:

public class MyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var context = CurrentHttpContext.Instance();
        // stuff
    }
}
peco
  • 3,510
  • 1
  • 18
  • 24