This is a migrated thread and some comments may be shown as answers.

Mock HttpContext

9 Answers 875 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
cecilUOA
Top achievements
Rank 1
cecilUOA asked on 11 Nov 2011, 05:12 AM
HttpContext currentContext = Mock.Create<HttpContext>(Constructor.Mocked);
Ambiguous match found.

 

 

HttpContext currentContext = Mock.Create<HttpContext>();

Object reference not set to an instance of an object.

These are the two errors I am getting. My Question is what is the current way to mock HttpContext constructor.

I am using JustMock Trial Version Q2 2011 (2011.2.713.2)

Thanks

9 Answers, 1 is accepted

Sort by
0
Ricky
Telerik team
answered on 14 Nov 2011, 12:56 PM
Hi Doug,

Thanks for reporting the issue. However, ambiguous exception during Mock.Create<HttpContext> using Constructor.Mocked is now fixed and will be available in the coming Q3 build this week.

On your second issue, the null reference exception thrown by the constructor itself for the required arguments. In that regard you can also try the method shown in the following example to mock HttpContext class:
var expectedException = new ArgumentException();
 
            var request = new HttpRequest(string.Empty, "http://telerik.com", null);
            var response = new HttpResponse(null);
 
            HttpContext context = Mock.Create<HttpContext>(() => new HttpContext(request, response));
 
            bool called = false;
 
            Mock.Arrange(() => context.Error).DoInstead(() => called = true).Returns(expectedException);
 
            Assert.Equal(context.Request, request);
            Assert.Equal(context.Error, expectedException);
            Assert.True(called);



Kind regards,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
cecilUOA
Top achievements
Rank 1
answered on 18 Nov 2011, 04:25 AM

I dont know what it is with HttpContext.Current. But it's just not happening. I tried both with Constructor.Mocked and with my own request, response object. The creation step does not throw an exception, but HttpContext.Current is still null.

//var currentContext = Mock.Create<HttpContext>(Constructor.Mocked);
var httpResponse = new HttpResponse(null);
var httpRequest = new HttpRequest(string.Empty, "http://foo.com/", null);
var currentContext = Mock.Create<HttpContext>(() => new HttpContext(httpRequest, httpResponse));
  
Mock.SetupStatic<HttpContext>();
Mock.Arrange(() => HttpContext.Current).Returns(currentContext);

Please take another look, thanks.
0
Ricky
Telerik team
answered on 18 Nov 2011, 12:08 PM
Hi Doug,

Thanks again for posting the issue. However HttpContext is a special class like mscorlib , therefore please make sure that you have applied [MockClass] attribute on top of the test class.

With the attribute in place, i tried the following and it worked as expected:

var httpResponse = new HttpResponse(null);
 
var httpRequest = new HttpRequest(string.Empty, "http://foo.com/", null);
 
var currentContext = Mock.Create<HttpContext>(() => new HttpContext(httpRequest, httpResponse));
 
Mock.Arrange(() => HttpContext.Current).Returns(currentContext);
 
Assert.IsNotNull(HttpContext.Current);

Here to mention that you generally dont require the Mock.SetupStatic<HttpContext>() unless you are doing strict mocking or want to fake the static constructor.

Moreover, I have used the latest Q3 build for testing out the problem.


Kind Regards,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
cecilUOA
Top achievements
Rank 1
answered on 20 Nov 2011, 09:47 PM
Thank you so much for the help so far, but I am still stuck. Looks like the HttpContext.Current is not null, although examining it during the debugging in Visual Studio shows otherwise. But ok, maybe debugger is bypassing the mocking. At the end I want to mock HttpContext.Current.Request.Url.AbsoluteUri to return a url I specified. Here is the complete code i have in mind, and "Constructor on type 'System.Web.HttpRequest' not found." is the error I am getting now. Shouldnt Recursive Mocking apply here?

[TestClass]
[MockClass]
public class JustMockTest1
{
    [TestMethod]
    public void GetAbsoluteUri()
    {
        //var currentContext = Mock.Create<HttpContext>(Constructor.Mocked);
        var httpResponse = new HttpResponse(null);
        var httpRequest = new HttpRequest(string.Empty, "http://lms.auckland.ac.nz/", null);
        var currentContext = Mock.Create<HttpContext>(() => new HttpContext(httpRequest, httpResponse));
        //Mock.SetupStatic<HttpContext>();
        Mock.Arrange(() => HttpContext.Current).Returns(currentContext);
        //Mock.Arrange(() => HttpContext.Current.Request).Returns(httpRequest);
        Assert.IsNotNull(HttpContext.Current);
        Assert.IsNotNull(HttpContext.Current.Request);
        //Exception has been thrown by the target of an invocation.
        Mock.Arrange(() => HttpContext.Current.Request.Url.AbsoluteUri).Returns("http://lms.auckland.ac.nz/default.aspx");
        var str = HttpContext.Current.Request.Url.AbsoluteUri; //Object reference not set to an instance of an object.
        Assert.Equals(str, "http://lms.auckland.ac.nz/default.aspx");
    }
}
0
Ricky
Telerik team
answered on 22 Nov 2011, 01:19 PM
Hi Doug,
Thanks again for the code sample. However, you can write the test in the following way that works as expected:

var httpResponse = new HttpResponse(null);
var httpRequest = new HttpRequest(string.Empty, "http://lms.auckland.ac.nz/", null);
var currentContext = Mock.Create<HttpContext>(() => new HttpContext(httpRequest, httpResponse));
 
Mock.Arrange(() => HttpContext.Current).Returns(currentContext);
 
Assert.IsNotNull(HttpContext.Current);
Assert.IsNotNull(HttpContext.Current.Request);
 
var request = HttpContext.Current.Request;
 
Mock.Arrange(() =>request.Url.AbsoluteUri).Returns("http://lms.auckland.ac.nz/default.aspx");
 
var str = HttpContext.Current.Request.Url.AbsoluteUri; //Object reference not set to an instance of an object.
 

Here in the following line:
var currentContext = Mock.Create<HttpContext>(() => new HttpContext(httpRequest, httpResponse));

You are already setting the request object , therefore you can either write the test as above or can add an extra line:

Mock.Arrange(()=> HttpContext.Current.Request).CallOriginal();

However, I found that the above line is producing an exception similar to your one, therefore will include the fix in the service pack release or if you can create a ticket then i can send you an internal build.


Kind regards,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
cecilUOA
Top achievements
Rank 1
answered on 23 Nov 2011, 03:01 AM
Once again thanks for the help, your solution works great, however it seems to only mock the calls within the unit test project, as soon as it's called outside that scope (ie. when called in the actual code that we are trying to unit test on) HttpContext.Current returns null again. No easy way to paste the code here.

Bascially I have two project, Project A the actual sharePoint projec, Project B the unit testing project
The mocking for HttpContext.Current is setup in Test Method, then I call the actual code in Project A, which will make use of HttpContext.Current. And that returns null.

Thanks
0
Ricky
Telerik team
answered on 25 Nov 2011, 08:56 AM
Hi Doug,

Thanks again for reporting the issue. Yes you are right that there is a bug with HttpContext.Current when mocked from outside the scope of the test class. This is due to the MockClassAtrribute usage bug. If you apply MockClassAttribute on top of the class from Project A, you will see that it will work as expected.

However, we are working on this and a fix will be available in the Q3 SP1 shortly.


Kind Regards,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
cecilUOA
Top achievements
Rank 1
answered on 11 Apr 2012, 02:47 AM

Here is my sample code, please take a look.

In it I have a code class (Class1.cs), my actual code that I want to unit test, it queries the httpRequest for a query string value.
In my unit test code (Test.cs), I want to mock the query string return value.

TestCase1 which is just plain mocking the HttpContext.Current. And that also give me the NullReferenceException.

Class1.cs

namespace HttpContextTest
{
    using Telerik.JustMock;
  
    [MockClass]
    public static class CodeClass
    {
        public static string AMethod()
        {
            return Utility.CurrentHttpContext.Invoke().Request[Utility.QueryStringCourseGroupKey]; // NullReferenceException
        }
    }
}

Utility.cs

namespace HttpContextTest
{
    using System;
    using System.Web;
  
    using Telerik.JustMock;
  
    [MockClass]
    public static class Utility
    {
        public const string QueryStringCourseGroupKey = "courseGroup";
  
        public static Func<HttpContext> CurrentHttpContext { get; set; }
  
        public static void Reset()
        {
            CurrentHttpContext = () => HttpContext.Current;
        }
    }
}

Test.cs

 

namespace HttpContextTest
{
    using System.Web;
  
    using NUnit.Framework;
  
    using Telerik.JustMock;
  
    [TestFixture, MockClass]
    public class Test
    {
        [Test]
        [TestCase("current")]
        public void TestCase(string expected)
        {
            // Setup
            var httpResponse = Mock.Create<HttpResponse>();
            var httpRequest = Mock.Create<HttpRequest>(Constructor.Mocked);
            var httpContext = Mock.Create<HttpContext>(Constructor.Mocked);
            Mock.Arrange(() => httpContext.Request).Returns(httpRequest);
            Mock.Arrange(() => httpContext.Response).Returns(httpResponse);
            Mock.Arrange(() => HttpContext.Current).Returns(httpContext);
            Mock.Arrange(() => httpRequest[Utility.QueryStringCourseGroupKey]).Returns(expected);
  
            // action
            Utility.Reset();
            var actual = CodeClass.AMethod();
  
            // assert
            Assert.AreEqual(actual, expected);
        }
  
        [Test]
        [TestCase("current")]
        public void TestCase1(string expected)
        {
            var httpResponse = Mock.Create<HttpResponse>();
            var httpRequest = Mock.Create<HttpRequest>(Constructor.Mocked);
            var httpContext = Mock.Create<HttpContext>(Constructor.Mocked);
            Mock.Arrange(() => httpContext.Request).Returns(httpRequest);
            Mock.Arrange(() => httpContext.Response).Returns(httpResponse);
            Mock.Arrange(() => HttpContext.Current).Returns(httpContext);
            //Mock.Arrange(() => HttpContext.Current.Request).Returns(httpRequest);
  
            Mock.Arrange(() => httpRequest[Utility.QueryStringCourseGroupKey]).Returns(expected);
  
            var actual = HttpContext.Current.Request[Utility.QueryStringCourseGroupKey];
  
            Assert.AreEqual(actual, expected);
        }
    }
}

 

 

 

Thanks

0
Ricky
Telerik team
answered on 13 Apr 2012, 04:49 PM
Hi Doug,

Thanks again for reporting the issue.  However, I found out that the first test is failing because HttpContext.Current is executed via Func delegate that is on the other hand not executing the appropriate mock setup and thus returning null. I am adding this as an issue which you can follow here:

http://www.telerik.com/support/pits.aspx#/public/justmock/10713
 
Sorry for the inconvenience.


 
Kind regards,
Mehfuz
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
General Discussions
Asked by
cecilUOA
Top achievements
Rank 1
Answers by
Ricky
Telerik team
cecilUOA
Top achievements
Rank 1
Share this question
or