views:

307

answers:

5

I'm currently looking into unit testing for a new application I have to create. I've got the basic testing going nicely (testing the ActionResult classes is pretty nice). One thing I do want to make sure though, is that a viewpage exists in my solution. I'm not 100% sure my test is correct, so if anyone had suggestions, please don't hesitate!

This is a test I have to check that my login method on my security controller is doing the right thing:

[TestMethod]
public void Login()
{
    var authProvider = new Mock<IAuthenticationProvider>();
    var controller = new SecurityController(authProvider.Object);

    var result = controller.Login() as ViewResult;

    Assert.IsNotNull(result, "ActionResult should be of type ViewResult.");
    Assert.AreEqual(result.ViewName, "login", "Does not render login page.");
}

My explanation of the test would be:

  • call the method 'Login' on the controller
  • Confirm it's rendering a view (by checking if it returns a ViewResult object)
  • Confirm it's rendering the right view (by checking the viewname)

What I would like to have is a third assert, to see if the view to be rendered actually exists.

Some secondary questions I have would be:

  • Should I split this test up?
  • Should I rename it (like, err, LoginRendersCorrectView or something)

Thanks!


Note: I'm explicitly trying to avoid having to check the filesystem. I'm sort of hoping for a way to use the ViewEngine to confirm the view actually exists.

A: 

If you're using beta, your code-behind file will create a class for the View which you can check for using reflection.

Otherwise, you could check for the file to exist in the right location.

ajma
Checking the filesystem directly is something I want to specifically avoid. It has crossed my mind, but it feels wrong to do it like that.
Erik van Brakel
+3  A: 
  • No, I don't think you should split the test up as long as its just mainly a third assert and not very much more code.

  • Yes, I think a more descriptive name would be helpful.

  • Since you've verified it has the correct view name already, wouldn't simply successfully rendering the view verify its existence?

I think that its great you are working on complete test coverage but here I feel like there might be more effective use of your time if you were able to move on to the part where you verify that the units that perform the actual specific login functions (such as verifying password hashes or whatever) are working correctly.

Jason Livesay
The reason I want to verify a view exists is that I've already encountered a situation where my application would test fine, but I forgot to add the view (even though it could be a default view). I want to prevent my application from throwing an error when I can catch that with a test.
Erik van Brakel
OK. Can you try to render the view, check some basic feature of the output, if it fails after the first two asserts then you know the view doesn't exist?
Jason Livesay
+1  A: 

ITA with Jason, but I don't think what you are trying to do actually contributes to test coverage. After all, rendering it and testing behavior will already cover whether or not it exists.

Lots of developers go overboard when they first get bitten by the TDD bug. They want test failures to tell them exactly what is wrong so they don't have to dig in and debug. That isn't the primary purpose of testing; testing is for verifying correct behavior so you don't ship bad software. When something is wrong, then you can debug. There's no need to have a test harness so specific that the testing engine knows exactly what the issue is.

entaroadun
+1  A: 

Knowing that the view exists in the solution is not terribly useful. What you really care about is that the view will be deployed, since your users (I hope) don't run your site within Visual Studio. In other words, what you are asking for is not a unit test, but an integration test. Therefore, you should use an appropriate tool for the job. Consider a web testing framework like Selenium.

Craig Stuntz
A: 

You could try to use the FindView method of the ViewEngineCollection object you have in the ViewResult to check if the MVC framework can locate the View.

As other have suggested I think this 3'rd Assert (that the view actually exists) is not something that will add real value to your tests, but nevertheless, here's the code to check for existance:

var viewEngineResult = result.ViewEngineCollection.FindView(controller, result.ViewName, result.MasterName);
if (viewEngineResult == null)
    ... not found ...

Hope this helps.

Florin Sabau