tags:

views:

114

answers:

3

I've been using ASP.NET MVC for a little while now and seem to find myself constantly returning things other than ActionResult from my controllers. I obviously return ViewResults but also JSonResults and also a couple of custom results that we've built in house.

I'm wondering tho, if, instead of declaring my controller methods like:

public ActionResult Index()

I should start declaring them as

public ViewResult Index()

or

public JSonResult Search()

if I always know that the Index action on my controller will always return a ViewResult or the Search action on my controller will always return a JSonResult?

EDIT: Just to clarify, I'm talking specifically about situations where I will always want a specific type of ActionResult to be returned.

A: 

I would leave it as the generic ActionResult. If you make it the specific result and change it later some, if not all, of your unit tests will need to be rewritten to accommodate the change. This will make your unit tests more brittle than they need to be.

EDIT: additionally, by leaving it as an ActionResult, you allow yourself the ability to return various different results based on you action logic. For example, the normal flow of your method might return a RedirectResult, but you may have error paths that return a ViewResult or HttpUnauthorizedResult. If you type your method more strongly than needed originally, you may end up having to unnecessarily refactor it and your tests as you add in alternative results later.

The bottom line is that I don't see any real advantages and, at least a couple, disadvantages.

tvanfosson
Why would my unit tests need to change? If I'm testing for a specific result type, shouldn't I want my unit tests to fail if something other than that result is returned? If I'm changing the return type, wouldn't I also want to change my tests first to cater for this?
lomaxx
When you create a unit test (at least with MSTest), it will fill in the result type for the actual result for you. If you were to leave that code alone, in the tests that aren't actually checking for the correct result type -- but perhaps making sure that a DB insert occurred, for example -- that test would now be dependent on the result type when it doesn't need to be. That's what I mean by brittle. If, on the other hand, you refactored the tests so that you declare using var, this wouldn't necessarily be a problem (I often do this anyway) -- but you have to remember to do it.
tvanfosson
I don't know about you but my pages are never really complete until right near the end. I'm always adding bits here and there. Binding myself to a particular type would mean more work for me. leaving it as ActionResult allows me the flexibility to add other classes to my FormViewModel.
griegs
A: 

By declaring a more specific return type you're gaining a little bit more of compiler type checking that you now don't have to cover in unit tests.

You would be binding yourself, however, to that type, and would have to revert if that changes. A common example is if you have to redirect the user elsewhere on some special conditions by returning a RedirectResult.

Oren Trutner
You could make the same argument for any method that returns any type. If I want to return multiple result types, then I agree, I should probably leave it as action result, but if the desired behaviour is to always return a specific action result, is there any reason why I shouldn't return that specific action result type?
lomaxx
+3  A: 

I vote yes for two reasons.

  1. You are explicitly declaring what you expect the method to return and the compiler will catch any attempt to do otherwise. No need for a unit test that does a Assert( result is ViewResult).

  2. You have to cast the result to the expected type in your tests when examining any properties unique to that result type (For example, checking Url property of the RedirectResult). Simply declaring the test variable as var removes any brittleness incurred by changing types.

Paul Alexander
I'd have to say this does make more sense to me.
lomaxx