2

This is the first time I am using moq and cannot really find a good tutorial on how to use it for application variables. I in my controller i am calling a method that calls HttpContext.Current.Application["TheConnectionString"] and im my global.asax I declared and initialized Application["TheConnectionString"] = "MyConnectionString"

[TestMethod]
public void TestGetCompanyList()
{
    string applicationValue = "MyConnectionString";
    var mockApplication = new Mock<HttpApplicationStateBase>();
    mockApplication.SetupSet(s => s["TheConnectionString"] = It.IsAny<string>()).Callback((string name) => applicationValue = (string)val);
    mockApplication.SetupGet(s => s["TheconnectionString"]).Returns(() => applicationValue);

    var request = new Mock<HttpRequestBase>();
    var context = new Mock<HttpContextBase>();

    request.SetupGet(x => x.Headers).Returns(new System.Net.WebHeaderCollection {{"X-Requested-With", "XMLHttpRequest"}});
    context.SetupGet(ctx => ctx.Request).Returns(request.Object);
    context.SetupGet(x => x.Application).Returns(applicationValue);


    var accController = new AccSerController();
    CInt cInt = new CInt();
    cIn.Iss = "Other";
    cIn.Tick = "BK";
    var result = accController.GetClist(cIn) as IEnumerable<CList>;
    Assert.IsNotNull(result);
}

I dont know how to "connect" the application value to the controller.

Edit:

My controller:

public class AccSerController : ApiController
{
    [System.Web.Http.HttpPost]
    public dynamic GetCList([FromBody]CompanyInput cInput)
    {
        AccSerFacade accService = new AccSerFacade();
        IEnumerable<CompanyListResult> cList = accService.GetCList(cIn);
        return cList;
    }

1 Answer 1

4

I in my controller i am calling a method that calls HttpContext.Current.Application["TheConnectionString"]

OK, that's where we should start with rule number one:

HttpContext.Current == Arch Enemy Of Unit Testing. Search for every single occurrence of this static call in your application and get rid of it.

So let's remove this evil call in your controller by replacing it with the proper abstraction if you want to stand any chances of mocking and testing it:

public ActionResult GetClist(CInt model)
{
    string conStr = (string)this.HttpContext.Application["TheConnectionString"];
    ...
}

Now you can write a proper unit test:

// arrange
string applicationValue = "MyConnectionString";
var mockApplication = new Mock<HttpApplicationStateBase>();
mockApplication.SetupGet(s => s["TheConnectionString"]).Returns(applicationValue);

var request = new Mock<HttpRequestBase>();
var context = new Mock<HttpContextBase>();

request.SetupGet(x => x.Headers).Returns(new WebHeaderCollection { { "X-Requested-With", "XMLHttpRequest" } });
context.SetupGet(ctx => ctx.Request).Returns(request.Object);
context.SetupGet(ctx => ctx.Application).Returns(mockApplication.Object);

var sut = new AccSerController();
sut.ControllerContext = new ControllerContext(context.Object, new RouteData(), sut);

CInt cInt = new CInt();
cIn.Iss = "Other";
cIn.Tick = "BK";

// act
var actual = accController.GetClist(cIn);

// assert
Assert.IsNotNull(actual);
Sign up to request clarification or add additional context in comments.

2 Comments

currently I have the application variable declared in the global.asax file. Where and why should i put it in an ActionResult method?
I am also getting an error at line sut.ControllerContext = new ControllerContext(context.Object, new RouteData(), sut); under the sut at the end. The error is Argument type 'projectname.AccSerController is not assignable to parameter type 'System.web.mvc.ControllerBase'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.