views:

56

answers:

3

Hi Is there a way to mock request params, what is the best approach when testing to create fake request values in order to run a test

would some thing like this work?

        _context = MockRepository.GenerateStub<HttpContext>();
         request = MockRepository.GenerateStub<HttpRequest>();

        var collection = new NameValueCollection();
        collection.Add("", "");

        SetupResult.For(request.Params).Return(collection);
        SetupResult.For(_context.Request).Return(request);
A: 

HttpRequest features a ton of non-virtual properties and methods. You're never going to be able to mock it. If you're accessing it from Page.Request, you can't even instantiate a new one and set its values for your test. This is one of the reasons that the UI rarely (if ever) gets automated tests; it's frequently just not possible. That's why we use patterns that allow automated testing such as MVC and MVVM: by pushing as much processing logic as we can to a separate class that is testable, we reduce the amount of manual testing we need to do.

The best bet you have available to you is to create a class that you can mock (i.e. with virtual methods or sporting and cast as an interface) and only access the HttpRequest through that class.

For example, if you were wanting to get certain cookie values as part of your page processing, you might create a CookieHandler class as follows:

public class CookieHandler
{
    private HttpRequest CurrentRequest;

    public CookieHandler(HttpRequest request)
    {
        CurrentRequest = request;
    }

    public virtual HttpCookie UserLanguagePreference
    {
        get
        {
             return CurrentRequest.Cookies["UserLanguagePreference"].Name;
        }
    }
}

This isn't an ideal class, it's just for example; because UserLanguagePreference is virtual, it can be mocked by Rhino. You might make CookeHandler a singleton (replaceable in your tests), you might use property-based injection on your UI Page, or you might use a DI framework like Unity.

The point is that you can't test everything with automated unit tests, so don't bother. Test as much as you can and save the rest for integration and manual user acceptance tests.

Randolpho
Hi thanks for your help, Ive edited the question, can you let me know if this is possible?
Matthew
+1  A: 

As said, you really don't want to have too many direct dependencies on HttpRequest as it is pretty bad design in this day and age. That fact noted, you should look at mocking HttpRequestBase as that is using rhino-mock friendly virtual methods internally.

Wyatt Barnett
Very nice suggestion; I was unaware of HttpRequestBase. But that led me to HttpRequestWrapper, which is probably the best bet for the original asker.
Randolpho
A: 

Look into MVCContrib.TestHelper. It uses Rhino.Mocks to create a complete testing environment for controllers (mock HttpContext, Request, Response, Session, etc...). See: http://stackoverflow.com/questions/3080814/how-do-i-use-rhino-mocks-to-mock-a-controllercontext

Patrick Steele