1

I am new to unit testing and trying to learn TDD, but I cannot figure out how to test this. I spent two days on it already (don't worry it is not for an employer, so please no smart answers).

I wrote a controller that I want to test, I need to assign a value to "Choice". Simplified, it looks like this:

    public ActionResult Index()
    {
          string s = Request["Choice"];
          return View(new MyList.GetList(s));
    }

How do I assign a value to "Choice" in the test or can I? In the application, the value of "Choice" is assigned by a radiobutton in a form in the page view. This is my test in psuedocode:

    [TestMethod()]
    public void IndexTest()
    {
          CategoryController target = new CategoryController();
          var result = target.Index() as ViewResult;
          MyList actual = result.ViewData.Model as MyList;

          // etc ...

          Assert.AreEqual(expected.List, actual.List);
    }

Thanks, Mario

Mario
  • 11
  • 2

3 Answers3

4

I'm pretty sure that you can just accept choice as a parameter to your action method. Then no shenanigans are necessary:

public ActionResult Index(string choice)
{
      return View(new MyList.GetList(choice));
}

This wouldn't work if choice is coming from a cookie or server variable, but I assume that you're expecting it from either the query string or form post.

John Bledsoe
  • 17,142
  • 5
  • 42
  • 59
  • +1. Using `Request` in that manner is rather "low level" for ASP.NET MVC. Let the model binder do this work for you. – Matt Greer May 11 '11 at 19:49
  • Sorry, this didn't work. I tried it already. My first hit has no parameter. – Mario May 11 '11 at 20:00
  • 1
    If by "my first hit" you mean the initial GET request that doesn't include the POST-ed choice parameter, then the method should still execute, just with a null value in the choice variable. Your method should be able to handle that case. Alternately, you could create separate methods for [HttpGet] and [HttpPost] to handle the difference. – John Bledsoe May 11 '11 at 20:07
  • I have a [HttpGet] and a [HttpPost] method. I am testing the GET method. There are 2 cases, Index() is called without a parameter. Within the method, Request["Choice"] is called. When an Actionlink calls the method, Request["Choice] returns a null, and that's ok. It is a proper usage. But when the View Form is submitted "Choice" has a value. – Mario May 11 '11 at 20:19
  • I'm sorry but I'm not sure I can get what's going on without an expanded code sample. I still think that you can make this work with action parameters but would need to see what you're trying to do in order to figure out how to help :-) – John Bledsoe May 11 '11 at 20:24
  • You are right John, I can invoke ActionLink and pass it an initial parameter. This may be the simplest way to put this issue to sleep. It is not a critcal issue and I do not want to get into mocking to solve this problem. Let me try that and see if I can get around the problem. Thanks. – Mario May 11 '11 at 20:29
  • And yes Matt, I think I have to get rather "low level" to assign "Choice". It is above my head right now, so I will let it go. Thanks. – Mario May 11 '11 at 20:31
1

Basically you don't want to test that Request works properly.

Request is something that you didn't develop, so you can exclude it from your test by wrapping it.

Example:

public ActionResult Index()
{
    string s = GetChoice();
    return View(new MyList.GetList(s));
}

public virtual string GetChoice()
{
    return Request["Choice"];
}

and then you later on you can fake out the GetChoice method in your unit test.

Your test might look like this:

public void Index_WhenCalled_ReturnsMyListFromChoice()
{
    var fake = MockRepository.GenerateStub<SomeController>();
    fake.Expect(x => x.GetChoice()).Return("some fake choice");

    var returnedView = fake.Index();

    Assert(/*assert something here */);
}
Joseph
  • 25,330
  • 8
  • 76
  • 125
1

As noted, strongly typed action methods are your friend here, use them.

But if you need to much around and fake HTTP stuff, you should check out the MvcContrib TestHelpers; they will help you test lots of this stuff.

Wyatt Barnett
  • 15,573
  • 3
  • 34
  • 53