Make Fake MVC Objects for testing

If you need to create some Fake MVC objects for testing MVC objects then here you are:

FakeControllerContext

using System.Collections.Specialized;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.SessionState;

using MvcContrib.TestHelper.Fakes;

public class FakeControllerContext : ControllerContext
{
    public FakeControllerContext(IController controller)
        : this(controller, null, null, null, null, null, null)
    {
    }

    public FakeControllerContext(IController controller, HttpCookieCollection cookies)
        : this(controller, null, null, null, null, cookies, null)
    {
    }

    public FakeControllerContext(IController controller, SessionStateItemCollection sessionItems)
        : this(controller, null, null, null, null, null, sessionItems)
    {
    }
        
    public FakeControllerContext(IController controller, NameValueCollection formParams)
        : this(controller, null, null, formParams, null, null, null)
    {
    }
        
    public FakeControllerContext(IController controller, NameValueCollection formParams, NameValueCollection queryStringParams)
        : this(controller, null, null, formParams, queryStringParams, null, null)
    {
    }
        
    public FakeControllerContext(IController controller, string userName)
        : this(controller, userName, null, null, null, null, null)
    {
    }
        
    public FakeControllerContext(IController controller, string userName, string[] roles)
        : this(controller, userName, roles, null, null, null, null)
    {
    }
        
    public FakeControllerContext
        (
            IController controller,
            string userName,
            string[] roles,
            NameValueCollection formParams,
            NameValueCollection queryStringParams,
            HttpCookieCollection cookies,
            SessionStateItemCollection sessionItems
        )
        : base(new FakeHttpContext(new FakePrincipal(new FakeIdentity(userName), roles), formParams, queryStringParams, cookies, sessionItems), new RouteData(), (Controller)controller)
    { }
}

FakeHttpContext

using System;
using System.Collections.Specialized;
using System.Security.Principal;
using System.Web;
using System.Web.SessionState;

public class FakeHttpContext : HttpContextBase
{
    private readonly FakePrincipal principal;
    private readonly NameValueCollection formParams;
    private readonly NameValueCollection queryStringParams;
    private readonly HttpCookieCollection cookies;
    private readonly SessionStateItemCollection sessionItems;

    public FakeHttpContext(FakePrincipal principal, NameValueCollection formParams, NameValueCollection queryStringParams, HttpCookieCollection cookies, SessionStateItemCollection sessionItems)
    {
        this.principal = principal;
        this.formParams = formParams;
        this.queryStringParams = queryStringParams;
        this.cookies = cookies;
        this.sessionItems = sessionItems;
    }

    public override HttpRequestBase Request
    {
        get
        {
            return new FakeHttpRequest(this.formParams, this.queryStringParams, this.cookies);
        }
    }

    public override IPrincipal User
    {
        get
        {
            return this.principal;
        }
        set
        {
            throw new NotImplementedException();
        }
    }

    public override HttpSessionStateBase Session
    {
        get
        {
            return this.sessionItems == null ? null : new FakeHttpSessionState(this.sessionItems);
        }
    }

}

FakeHttpRequest

using System.Collections.Specialized;
using System.Web;

public class FakeHttpRequest : HttpRequestBase
{
    private readonly NameValueCollection formParams;
    private readonly NameValueCollection queryStringParams;
    private readonly HttpCookieCollection cookies;

    public FakeHttpRequest(NameValueCollection formParams, NameValueCollection queryStringParams, HttpCookieCollection cookies)
    {
        this.formParams = formParams;
        this.queryStringParams = queryStringParams;
        this.cookies = cookies;
    }

    public override NameValueCollection Form
    {
        get
        {
            return this.formParams;
        }
    }

    public override NameValueCollection QueryString
    {
        get
        {
            return this.queryStringParams;
        }
    }

    public override HttpCookieCollection Cookies
    {
        get
        {
            return this.cookies;
        }
    }
}

FakeHttpSessionState

using System.Collections;
using System.Collections.Specialized;
using System.Web;
using System.Web.SessionState;

public class FakeHttpSessionState : HttpSessionStateBase
{
    private readonly SessionStateItemCollection sessionItems;

    public FakeHttpSessionState(SessionStateItemCollection sessionItems)
    {
        this.sessionItems = sessionItems;
    }

    public override void Add(string name, object value)
    {
        this.sessionItems[name] = value;
    }

    public override int Count
    {
        get
        {
            return this.sessionItems.Count;
        }
    }

    public override IEnumerator GetEnumerator()
    {
        return this.sessionItems.GetEnumerator();
    }

    public override NameObjectCollectionBase.KeysCollection Keys
    {
        get
        {
            return this.sessionItems.Keys;
        }
    }

    public override object this[string name]
    {
        get
        {
            return this.sessionItems[name];
        }
        set
        {
            this.sessionItems[name] = value;
        }
    }

    public override object this[int index]
    {
        get
        {
            return this.sessionItems[index];
        }
        set
        {
            this.sessionItems[index] = value;
        }
    }

    public override void Remove(string name)
    {
        this.sessionItems.Remove(name);
    }
}

FakePrincipal

using System.Linq;
using System.Security.Principal;

public class FakePrincipal : IPrincipal
{
    private readonly IIdentity identity;
    private readonly string[] roles;

    public FakePrincipal(IIdentity identity, string[] roles)
    {
        this.identity = identity;
        this.roles = roles;
    }

    public IIdentity Identity
    {
        get { return this.identity; }
    }

    public bool IsInRole(string role)
    {
        return this.roles != null && this.roles.Contains(role);
    }
}

The original article and source is from Stephen Walter Faking the Controller Context

Unit Testing a Private Method

With Visual Studio keep changing the way you create unit tests I thought I’d document down how to test a private method the easy way.

Here is a simple HomeController and we want to test that the GetPageSize method return 20 in a unit test.

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var pageSize = GetPageSize();
        return View(pageSize);
    }

    private int GetPageSize()
    {
        return 20;
    }
}

As GetPageSize is a private method we’ll need to use the PrivateObject class to return the methods result, this is quite easy, from the Unit Test project make sure you have a reference to your MVC project and then reference the HomeController and invoke the method you need the result back from:

[TestMethod]
public void CheckPageSizeIs20()
{
    PrivateObject privateObject = new PrivateObject(typeof(HomeController));
    int pageSize;
    pageSize = (int)privateObject.Invoke("GetPageSize");

    Assert.AreEqual(20, pageSize);
}

If you need to pass in parameters to the private method then you can pass in an anonymous type

var actual = (IEnumerable<ActivityData>)privateObject.Invoke("GetAllUnassignedJobs", new object[] { filterData, uniqueJobs });

Reference: How to test a class member that is not public

Thanks to Karthik for googleing the answer