views:

177

answers:

1

var mockedService = new Mock(); 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

+1  A: 

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.

Anderson Imes
@Anderson GetValueFromResource() method is using HTTPContext , so when that API call is encountered , the null reference exception is thrown . now what do i do. ? Any suggestions.?
vijaysylvester
I usually create a helper class that accesses HTTPContext for me that I use from my class that needs HTTPContext. This way you avoid referencing HTTPContext from everywhere. Alternatively there are quite a few tutorials on mocking HTTPContext on the internet. Regardless I hope you have learned that mocking what you are testing is not a good idea.
Anderson Imes
Can we Manually setup the HTTPCOntext Object . like this HTTPcontext context =new HTTPCOntext(Req,Res).After Manually constructing the Req and Res Objects.?
vijaysylvester
there's no reason to. The ResourceStore is meant to use HTTPContext, but if you mock it (like you should), it won't need to access HTTPContext... it'll be fake.
Anderson Imes
@Anderson Ya thanks Anderson , that perfectly worked in my case..
vijaysylvester