Aspnetcore.docs: Document unit testing Razor Pages

Created on 7 Sep 2017  路  13Comments  路  Source: dotnet/AspNetCore.Docs

Covers guidance on unit testing Razor Pages:

  • Enabling separation by removing logic from Razor files and keeping it in Page Models and injected services
  • Creating mockable services
  • Mocking framework intrinsic types in order to create Page Models that are being tested
P1

Most helpful comment

You're suggesting that I should skip the IsCompletedSuccessfully check and just go for ...

Yup. User code shouldn't really care about unwrapping the Task. async \ await does this nicely and we should guide them towards using it.

All 13 comments

@DamianEdwards can you assign a dev to write the sample we can use as a basis for the article? Once the sample code is written I can schedule and expedite.

@Rick-Anderson I can take a crack at the sample for this. I'm more familiar with the MVC approach, but I'd like to see how that translates to a RP app. If I do it (and likely run into trouble in the process), it might highlight some pitfalls that need to be covered in the topic. I just need a dev team member on the other end of the Dinosaur Disaster Hotline:tm:.

We're doing this as a ref topic, correct? ... Not rolling it into the RP tutorial but making a standalone topic under mvc/razor-pages for it.

Title? Unit Testing Razor Pages in ASP.NET Core

A few questions:

Question 1

The unit testing topic is tutorial-ish, and it doesn't do integration testing, which we'll have in this one. I was planning to write this topic as a reference topic with a sample. The other possibility would be adding a step to the RP tutorial (after the File Uploads step). Which way do u want to go? If this is going to be a RP tutorial step, then that answers my Question 2. If it's a ref topic, then Question 2 is still open.

Question 2

Assuming this will be a ref topic: The current unit testing topic lives over in the .NET Core docs at: https://docs.microsoft.com/dotnet/core/testing/unit-testing-with-dotnet-test. Will this also go over there and link into the TOC over here? If it's a new topic over here, then do you want the link in the TOC below (same level) or under (nested) the current unit testing link?

Question 3

I suggest building the sample and getting both sample and outline approved together by the dev team. If there's something amiss or missing, they can let us know before the writing effort gets underway. Ok?

  1. Write it as a ref topic.
  2. No, this stays in our repro.
  3. Yes, do the sample and outline.

@Rick-Anderson @danroth27 @scottaddie @pranavkm @DamianEdwards @javiercn

Proposed Title

Razor Pages integration and unit testing in ASP.NET Core

TOC Location

Docs/aspnetcore/testing/

UID

testing/razor-pages-testing

Topic type

Reference

Sample

https://github.com/guardrex/RazorPagesTestingApp

  • The app is a simple one page message system (List, Add, Delete, Delete All, Analyze).
  • It doesn't use the repository pattern; however, it does SoC for DAL by placing the EF-dB ops in the AppDbContext class.
  • It uses the in-memory dB.
  • Tests include:

    • Unit tests on the DAL.

    • Unit tests on the Index page model methods.

    • Integration testing on form actions use the TestFixture from the Testing Controllers topic and mostly test the page processing result.

  • Paint is still a bit wet on naming things. I'll prob change a few as I get into the topic.

Topic outline

  • Introduction
  • Unit testing the DAL
  • Unit testing the page model methods
  • Integration testing the app

    Philosophical issues

  • I'd like to keep the text lean and focused - teach through the sample as much as possible. Where possible, cross-link to the Testing Controllers and Integration testing topics.

  • IMO, it's better to explain the tests (briefly; one or two in each group) individually as opposed to showing several and describing them in en masse.
  • DAL tests create a fresh service provider for each dB context, which makes each unit test atomic. I prefer this approach, so I hope this approach has some support there.
  • RE: "Creating mockable services" ... we can add more. Let's see what makes sense. Not too many tho I hope. Since this concept applies to unit testing generally, I think it should mostly be addressed elsewhere in a more general topic on the subject.
  • RE: "Mocking framework intrinsic types in order to create Page Models that are being tested" ... Are you referring to the types needed to create a page model (PageContext, ActionContext, etc.)? (The sample does create these but doesn't use them in testing.) Or, do you mean performing Mock.Of certain interfaces outside of the RP infrastructure in a typical ASP.NET Core app? ... because if so, I also think that should go elsewhere.

@danroth27 can we get this outline and https://github.com/guardrex/RazorPagesTestingApp sample reviewed by EOW? @guardrex is waiting. cc @pranavkm @javiercn and cc @DamianEdwards for the outline

@Eilon @danroth27 can we get this outline and https://github.com/guardrex/RazorPagesTestingApp sample reviewed in the next 3 business days? @guardrex is waiting. cc @pranavkm @javiercn and cc @DamianEdwards for the outline

The outline looks good to me. I left a couple of comments in the commit for the sample (https://github.com/guardrex/RazorPagesTestingApp/commit/0e2470d75ec215d5573ddb9e3b1e1806450eac33#commitcomment-25509962) and doesn't look like they've been addressed.

@pranavkm Oh ... that's strange. I didn't get a GH ping on those, so I had no idea. I'll TAL now.

@pranavkm

These should use await.

Thanks ... yes, of course ... just an oversight. I'll fix 'um.

@Rick-Anderson [@]DamianEdwards looks like he had some ideas about mocking certain services and types used to create page models, and I'd like to make sure that what's in the sample is enough to cover his wishes. I wrote a bit about this in the Philosophical issues section of my comment :point_up:. Should we wait to see if others want to TAL? In the meantime, I'll flip over to the IHostingStartup prep work.

@pranavkm Oh ... I know why I set those up that way now. They're supposed to return a Task so that it can check IsCompletedSuccessfully, then it can use the result.Result to make sure the result is assignable to a List<Message>, get the actual messages, and then proceed to see if they match the expected messages.

Are you saying that this is a bad approach? ... I didn't think it would complete synchronously since it's returning a Task there ...

// Act
var result = db.GetMessagesAsync();

// Assert
Assert.True(result.IsCompletedSuccessfully);
var actualMessages = Assert.IsAssignableFrom<List<Message>>(result.Result);
Assert.True(Utilities.CompareMessages(expectedMessages, actualMessages));

You're suggesting that I should skip the IsCompletedSuccessfully check and just go for ...

// Act
var result = await db.GetMessagesAsync();

// Assert
var actualMessages = Assert.IsAssignableFrom<List<Message>>(result);
Assert.True(Utilities.CompareMessages(expectedMessages, actualMessages));

... after all; if the Task doesn't complete successfully, I think/hope it will fail gracefully (and I'll do a test on that to confirm it if you're saying this would be a better pattern to follow).

You're suggesting that I should skip the IsCompletedSuccessfully check and just go for ...

Yup. User code shouldn't really care about unwrapping the Task. async \ await does this nicely and we should guide them towards using it.

@pranavkm Gotcha, thanks. I'll fix it up.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rick-Anderson picture Rick-Anderson  路  3Comments

Raghumu picture Raghumu  路  3Comments

AnthonyMastrean picture AnthonyMastrean  路  3Comments

nenmyx picture nenmyx  路  3Comments

madelson picture madelson  路  3Comments