vijaysylvester
vijaysylvester

Reputation: 5030

How to Bypass HTTPContext Usage .?

var mockedService = new Mock<IService>();
mockedService.Setup(x => x.InterfaceMethod(args)).Returns(value);
_Service = mockedService.Object;
MyController controller =new MyController(_Service);

var result = (ViewResult)controller.Foo();

Now this Foo() Method contains the Following API Call

HttpContext.GetGlobalResourceObject(...,..);

But the HTTPContext is null, as i'm just unit testing , i have not Authenticated. and hence not populated the HTTPContext Object.

I cant set expectations on this class because the HTTPContext is sealed.

I've been searching in the net , but there were only samples to fake the HTTPContextBase

Now how do i get my Unit Test to Pass. Any Suggestions.?

thanks ,

vijay

Upvotes: 0

Views: 543

Answers (1)

Anderson Imes
Anderson Imes

Reputation: 25650

The problem is you are not setting up an expectation for the "Centres" method. When you mock an object all implementations are replaced with a Noop until you specify otherwise using an Expectation.

I'm guessing you mocked GetValueFromResource rather than Centres because Centres calls GetValueFromResource. If this is the case, mocking GetValueFromResource is likely a superfluous fake and you don't need it.

Also, as has been pointed out on several other Moq posts, you'll need to make sure that you are not mocking what you are testing. If you are actually trying to test MyController, you'd want to mock any dependencies it has, but not MyController itself. This will cause you no end of confusion.

Edit

Based on this feedback it seems you have learned that your true problem is that you need to mock HTTPContext. Mocking HTTPContext is nontrivial. There are a few tools that can do it natively, like Type Mock, but the problem is that ambient context is not testable.

What you should be doing is requesting dependencies that give you the information you need while abstracting away their implementation. For example, in your case it seems like you are using HTTPContext to access resources. If you need something like this a good interface you could use would be:

public interface IResourceStore
{
     object GetGlobalResource(string  classKey, string resourceKey);
}

Your default implementation would use HTTPContext, but now you have an interface you can mock and have your MyController class use, rather than HTTPContext directly.

Mock<IResourceStore> resourceStore = new Mock<IResourceStore>();
//setup resourceStore expectations here

MyController testingTarget = new MyController(_Service, resourceStore.Object);
//target assertions here

Hope this helps.

Upvotes: 1

Related Questions