1
\$\begingroup\$

I have the latest version of ReSharper installed and I am trying to write a Unit Test for my MVC controller. I need the Unit Test to:

Ensure the ViewModel passed to the View is of the correct type.

So here is what I have at the moment:

public void Create_HasCorrectViewModelType()
{
    // arrange
    var controller = new DraftController(_draftFacade);
    // act
    var viewResult = controller.Create() as ViewResult;
    var viewModel = viewResult.Model as DraftViewModel;
    // assert
    Assert.IsInstanceOfType(viewModel.GetType(), typeof(DraftViewModel));
}

I have issues with this, and would like to know your thoughts on the matter.

  1. the arrange makes sense. I am arranging / setting up my controller.
  2. Only the first line in the act seems logical to me. But me trying to grab the ViewModel isn't really an Act is it? Sounds like // arrange again!
  3. ReSharper complains that I am not doing null checks on viewResult and viewModel.

resharper null checks

I can go with ReSharper's recommendation, then my test becomes:

public void Create_HasCorrectViewModelType()
{
    // arrange
    var controller = new DraftController(_draftFacade);
    // act
    var viewResult = controller.Create() as ViewResult;
    var viewModel = viewResult?.Model as DraftViewModel;
    // assert
    if (viewModel != null) Assert.IsInstanceOfType(viewModel.GetType(), typeof(DraftViewModel));
}

Now ReSharper is happy, but then my Unit Test don't seem clean anymore! I feel like there are too many paths that can be taken for that one unit test.

Anyone else bugged by this? What can I do to improve this? Or is this the best I'm going to get?

Any help would be greatly appreciated.

\$\endgroup\$
5
  • \$\begingroup\$ Is there a reason why you don't want to do: Assert.IsInstanceOf<DraftViewModel>(viewResult?.Model); ? \$\endgroup\$
    – forsvarir
    Commented Feb 1, 2017 at 10:49
  • \$\begingroup\$ Isn't that the same thing but written differently? \$\endgroup\$
    – J86
    Commented Feb 1, 2017 at 11:01
  • \$\begingroup\$ At the moment, you're creating a variable viewModel that's only going to be populated if Model is castable to a DraftViewModel. Doing the same thing in your assert is redundant, you could just be asserting that viewModel != null. In your refactored, 'resharper friendly' approach you're going to get a pass if viewModel is null, which feels wrong. The approach I'm suggesting gets rid of the unnecessary variable and gives you a single line assert that confirms all of the expected linkages. If you don't care about them, then ignore resharper, you know the context better than it does. \$\endgroup\$
    – forsvarir
    Commented Feb 1, 2017 at 11:09
  • \$\begingroup\$ Can't you just assert that it's not null, AND assert it's the expected type as well? Definitely don't make the assert conditional on it not being null, else there is no assert and it passes when null. \$\endgroup\$
    – 404
    Commented Feb 1, 2017 at 11:35
  • \$\begingroup\$ This question might be more on-topic over at SoftwareEngineering.StackExchange.com . However, before posting please follow their tour and read "How do I ask a good question?", "What topics can I ask about here?" and "What types of questions should I avoid asking?". \$\endgroup\$
    – BCdotWEB
    Commented Feb 1, 2017 at 12:16

2 Answers 2

3
\$\begingroup\$

Asserting

if (viewModel != null) Assert.IsInstanceOfType(viewModel.GetType(), typeof(DraftViewModel));

You should use another assert and not an if

Assert.IsNotNull(viewModel);

Resharper even suggests this option:

enter image description here

Test name

Create_DraftFacade_ViewResultWithDraftViewModel

You might also want to reconsider the naming of your tests. Usually we use this pattern

TestedMethod/Property_TestData/Case_ExpectedResult

\$\endgroup\$
1
\$\begingroup\$

If controller.Create() is always creating ViewResult you must use explicit cast

var viewResult = (ViewResult)controller.Create();

else you must write another test for controller.Create().

The assertion code var viewModel = viewResult.Model as DraftViewModel; are using as, if the conversion isn't possible, as returns null so instead of IsInstanceOfType use IsNotNUll.

By the way, I can't get the act of your test by seeing your method name and I recommend you to read this article.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.