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

3 Answers 3

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.

Sign up to request clarification or add additional context in comments.

7 Comments

+1. Using Request in that manner is rather "low level" for ASP.NET MVC. Let the model binder do this work for you.
Sorry, this didn't work. I tried it already. My first hit has no parameter.
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.
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.
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 :-)
|
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 */);
}

1 Comment

You are right Joseph, I did not developed Request and I do not need to test Request.
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.

Comments

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.