3

I'm writing some unit tests and I have a scenario where, if a condition is true, a controller action should return a HttpNotFoundResult, otherwise it should return a ViewResult and have a specific Model inside of it.

As one of the tests (testing the scenario where it should return a ViewResult), I execute the action and then try and cast the result to a ViewResult. However, when using var result = myController.MyAction() as ViewResult (where result is an ActionResult), result always evaluates to null... but when I do var result = (ViewResult)myController.MyAction(), the result is casted just fine.

Why is this? Do I not understand the usage of as properly?

Relevant code:

// My controller
public class MyController
{
  .. 
  public ActionResult MyAction(bool condition)
  {
      if(condition)
         return HttpNotFound()
      return View(new object());
  }
}

// My test
public void MyTest()
{
  ....
  var controller = new MyController();
  var result = controller.MyAction(false) as ViewResult;
  // result should be casted successfully by as, but it's not, instead it's unll
  // however, this works
  var result = (ViewResult) controller.MyAction(false);
  // why is this?
}

EDIT: Full example with gist. Sorry, it seems that it doesnt' like the syntax highlighting. https://gist.github.com/DanPantry/dcd1d55651d220835899

Dan
  • 10,282
  • 2
  • 37
  • 64
  • The `as` operator is like a cast operation. However, if the conversion is not possible, as returns `null` instead of raising an exception. – Satpal Feb 06 '14 at 13:12
  • 1
    Yes, however, the explicit cast between `ActionResult` to `ViewResult` does not raise an exception - in fact, it works fine. So why does `ActionResult as ViewResult` return null? – Dan Feb 06 '14 at 13:13
  • A `ViewResult` inherits from `ActionResult` so `as` should always be able to cast it. Please can you post your *exact* code or a compilable demonstration of your issue (the code you have posted won't compile so that can't be it). – RB. Feb 06 '14 at 13:17
  • Sure thing, I'll update OP with a gist – Dan Feb 06 '14 at 13:19
  • Updated with gist. You will need Moq to compile the code. – Dan Feb 06 '14 at 13:23
  • Funny, I just executed the test in your gist, using both explicit casting and 'as', and they both worked. – rla4 Feb 06 '14 at 13:35
  • 1
    Consistently when I use that cast, across various projects, it does not work. Am compiling to .NET 4.5 (that is, when I use `ActionResult as ViewResult`, it never works, regardless of project) – Dan Feb 06 '14 at 13:36
  • Interestingly enough, when I installed Asp MVC 5 in both test and web project, the issue has dissipated (before, both ran MVC 4) – Dan Feb 06 '14 at 15:20
  • Interesting. I was testing in ASP.NET MVC 4, using .NET 4.0. I'm glad you solved it anyway :) – rla4 Feb 06 '14 at 16:47
  • 1
    It's not strictly solved because it still occurs in other projects. would be interesting to find the cause anyway so I'm keeping the questin open – Dan Feb 06 '14 at 17:11
  • any solution you found i'm facing same issue – Neo Jun 06 '17 at 05:01

1 Answers1

2

As no one has answered - I updated my ASP MVC to ASP MVC 5 and the tests then succeeded. I have a gut feeling that my test project was using ASP MVC 5, but the project containing the controller was running ASP MVC 4, and because they were from different binaries, the controller class could return a ViewResult in the shadow of ActionResult, but the test project could not convert from ViewResult to ActionResult because it's understanding of ViewResult was different.

Although this seems folly because one would assume I would get a build error in this case.

oh well, upgrading fixed it.

Dan
  • 10,282
  • 2
  • 37
  • 64
  • my both project are using mvc5 still getting null in unit test case any clue why? – Neo Jun 06 '17 at 04:58