chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
Welcome to Typemock Community! Here you can ask and receive answers from other community members. If you liked or disliked an answer or thread: react with an up- or downvote.
0 votes
I need to mock HttpContext and am having difficulty getting the code from the Adrian Spear blog link to work. Specifically its complaining about the reflective call to create the HttpSessionState.

Has anyone else had this problem and if so how did they fix it? I've cut and pasted the code exactly from the post and checked the argument count with reflector and everything *looks* right.

Here is the NUnit error:

AuthWebTests.UserHomePage.ShowLoginFormFirstTime : System.Reflection.TargetParameterCountException : Parameter count mismatch.

at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.ConstructorInfo.Invoke(Object[] parameters)
at AuthWebTests.UserHomePage.Setup() in H:SC5ClassLibraryExtranet Authentication TestsUserHomePage.cs:line 61

And its from this code:

ConstructorInfo[] constructorInfos = typeof(HttpSessionState).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);
this.httpSessionState = (HttpSessionState)constructorInfos[0].Invoke(new object[] { null, null, null, null, null, null, null, null });

I'm using VS2005(Pro) on Win2k with TypeMock 3.6.0.0 (Enterprise).

Thanks for any help!
asked by simonpro (1.8k points)

4 Answers

0 votes
Since version 3.6.0 TypeMock supports creating MockObjects with non default constructors.

So change
this.mockHttpSessionState = MockManager.Mock(typeof(HttpSessionState), Constructor.Mocked);

ConstructorInfo[] constructorInfos = typeof(HttpSessionState).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance);

this.httpSessionState = (HttpSessionState) constructorInfos[0].Invoke(new object[]{null, null, null, null, null, null, null, null})

To
this.mockHttpSessionState = MockManager.MockObject(typeof(HttpSessionState), Constructor.Mocked);
this.httpSessionState = (HttpSessionState) mockHttpSessionState.Object

Remember to change mockHttpSessionState to MockObject.

Actually a better Setup() will be.
[SetUp]
public void SetUp()
{
  // create a mocked HttpContext 
  this.mockHttpContext = MockManager.MockObject(typeof(HttpContext), Constructor.Mocked);
  this.httpContext = (HttpContext)mockHttpContext.Object;

  // create a mocked HttpSessionState 
  this.mockHttpSessionState = MockManager.MockObject(typeof(HttpSessionState), Constructor.Mocked);
  this.httpSessionState = (HttpSessionState) mockHttpSessionState.Object

  // create a HttpResponse 
  this.mockHttpResponse = MockManager.MockObject(typeof(HttpResponse), Constructor.Mocked);
  this.httpResponse = (HttpResponse)mockHttpResponse.Object;


(Here is the original code)
answered by scott (32k points)
0 votes
Hi,

Thanks for your reply. I changed my setup to your suggestion. However, you need one change as you'll get an ambiguous reflection error otherwise:

 this.mockHttpContext = MockManager.MockObject(typeof(HttpContext), Constructor.Mocked, new object[] { null });


However, I'm having trouble deciphering the expectations so that I can test my code correctly. Heres an example of the code I am testing:


            if (this.context.Session["attempts"] != null)
            {
                int attempts = (int)this.context.Session["attempts"];
            }
            else
            {
                this.context.Session["attempts"] = 1;
            }

            // This is what we expect to do next
            this.context.Session["previous action"] = "show login";
            this.context.Session["action"] = "accept login";


And my unit test looks something like this:

this.mockHttpContext.ExpectGet("Session", this.httpSessionState);

            this.mockHttpSessionState.ExpectGetIndex(null).Args("attempts");             
            // code should set attempts to 1 and set up the actions.
            this.mockHttpSessionState.ExpectSetIndex(1).Args("attempts", 1);
            this.mockHttpSessionState.ExpectSetIndex(1).Args("previous action", "show login");
            this.mockHttpSessionState.ExpectSetIndex(1).Args("action", "accept login");

            Presenter engine = new VelocityPresenter();
            engine.TemplatePath = String.Empty;
            LoginPage login = new LoginPage(this.httpContext, engine);

            // The call we are testing via mocks should also return true.
            Assert.IsTrue(login.ShowLoginForm(true)); 


Frankly I'm having trouble matching my expected sets and gets on the session to the setup required on my mock instance.

Can you provide any advice? I'm just shotgun debugging right now.

Thanks for your help so far! Its much appreciated! :D
answered by simonpro (1.8k points)
0 votes
You are welcome.

The best advice I can give is to use the tracer 8) you will see all the expectations set and called.

You can also use NaturalMocks for easier setting (well worth the price)

:idea: Here is one pointer:
as this.context.Session is called many times you should use ExpectGetAlways.
answered by scott (32k points)
0 votes
Nice :) I was just about to post that very thing. I wondered why I was getting null reference exceptions on Session and then it all worked. Doh! :)

For those that like to cut and paste, here is the correct session call line:

this.mockHttpContext.ExpectGetAlways("Session", this.httpSessionState);
answered by simonpro (1.8k points)
...