1

I am trying to unit test this application that uses application variables. There is no interfaces or virtual methods in the program and I am finding it difficult to make Moq work.

Class that uses Application Variables:

static string Username = HttpContext.Current.Application["Username"].ToString();

It is initialized in the global.asax file.

My Unit test:

[TestMethod]
public void TestGetCompanyList()
{
    Mock<HttpContextBase> context = new Mock<HttpContextBase>();
    Mock<HttpApplication> app = new Mock<HttpApplication>();

    context.Setup(ctx => ctx.ApplicationInstance).Returns(app); //ERROR

    var accountController = new AccountServiceController();

    accountController.ControllerContext = new ControllerContext(context.Object, new RouteData(), accountController); //ERROR


    CompInput cInput = new CompInput();
    cInput.IssuerName = "Addams";
    cInput.Ticker = "AD";
    var result = accountController.CompList(cInput) as IEnumerable<CompListResult>;
    Assert.IsNotNull(result);
}

The first error:

Error 4 The best overloaded method match for Moq.Language.IReturns<System.Web.HttpContextBase,System.Web.HttpApplication>.Returns(System.Web.HttpApplication)' has some invalid arguments

Error 5 Argument 1: cannot convert from 'Moq.Mock<System.Web.HttpApplication>' to 'System.Web.HttpApplication'

Second Error:

Error 6 The best overloaded method match for 'System.Web.Mvc.ControllerContext.ControllerContext(System.Web.HttpContextBase, System.Web.Routing.RouteData, System.Web.Mvc.ControllerBase)' has some invalid arguments

Error 7 Argument 3: cannot convert from 'Stocktrage.Investor.AccountServiceAPI.Controllers.AccountServiceController' to 'System.Web.Mvc.ControllerBase'

This is my first time using Moq (or any mocking tool), so I am not 100% sure if this can be done without interfaces.

User456789
  • 377
  • 2
  • 15
  • You shouldn't try to mock objects you don't own. You'll end up jumping through hoops and writing a lot of code – Jedediah Apr 22 '15 at 14:14
  • I own the objects. The `HttpContext.Current.Application["Username"]` is declared by me in the global asax file. – User456789 Apr 22 '15 at 14:15
  • You don't own HttpContext though, just a variable you're putting in there. Anyway, your problem is here: `context.Setup(ctx => ctx.ApplicationInstance).Returns(app);` Should be: `context.Setup(ctx => ctx.ApplicationInstance).Returns(app.Object);` – Jedediah Apr 22 '15 at 14:16
  • This may be of some help to you: http://stackoverflow.com/questions/1452418/how-do-i-mock-the-httpcontext-in-asp-net-mvc-using-moq – Jedediah Apr 22 '15 at 14:20

2 Answers2

0

The error messages make sense - the first error is due to passing the mock rather than its object like this:

Mock<HttpApplication> app = new Mock<HttpApplication>();
context.Setup(ctx => ctx.ApplicationInstance).Returns(app.Object);

and the second error looks like it's due to AccountServiceController not deriving from ControllerBase, for example; if it's an API Controller rather than MVC.

S__
  • 513
  • 4
  • 8
-1

try to explain this with a class Then you can mock:

public class MyConfigs
{
    public virtual object Username
    {
        get { return HttpContext.Current.Application["Username"]; }
        set { } 
    }


    public static MyConfigs GetConfig()
    {
        return new MyConfigs();
    }

    protected MyConfigs()
    {

    }

}

In your test you can do this:

       Mock<MyConfigs> configsMoq = new Mock<MyConfigs>();
        configsMoq.SetupProperty(x => x.Username, "REturn");
renefc3
  • 319
  • 2
  • 17
  • what is `MyConfigs` and `GetConfig`? – User456789 Apr 22 '15 at 14:28
  • @User456789 it's a class he has made for an example. – Jamie Rees Apr 22 '15 at 14:34
  • @User456789 this is a class to hide the call of HttpContext.Current.Application["Username"] on any place you have to access this all place you need, instead use this MyConfigs.GetConfig().Username. This help to make tests easy – renefc3 Apr 22 '15 at 14:42