From 9801181d9c3c4a4a5a0ddf07cc9c4a67807c9ab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 5 Nov 2020 15:43:42 +0300 Subject: [PATCH] Update Testing.md --- docs/en/Testing.md | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/docs/en/Testing.md b/docs/en/Testing.md index 2ef96c34ea..1112f612c1 100644 --- a/docs/en/Testing.md +++ b/docs/en/Testing.md @@ -337,6 +337,74 @@ public async Task Should_Not_Allow_To_Assign_Issues_Over_The_Limit() It is relatively easy to mock a single dependency. But, when your dependencies grow, it gets harder to setup the test objects and mock all the dependencies. See the *Integration Tests* section that doesn't require mocking the dependencies. +### Tip: Share the Test Class Constructor + +[xUnit](https://xunit.net/) creates a **new test class instance** (`IssueManager_Tests` for this example) for each test method. So, you can move some *Arrange* code into the constructor to reduce the code duplication. The constructor will be executed for each test case and doesn't affect each other, even if they work in parallel. + +**Example: Refactor the `IssueManager_Tests` to reduce the code duplication** + +````csharp +using System; +using System.Threading.Tasks; +using NSubstitute; +using Shouldly; +using Volo.Abp; +using Xunit; + +namespace MyProject.Issues +{ + public class IssueManager_Tests + { + private readonly Guid _userId; + private readonly IIssueRepository _fakeRepo; + private readonly IssueManager _issueManager; + private readonly Issue _issue; + + public IssueManager_Tests() + { + _userId = Guid.NewGuid(); + _fakeRepo = Substitute.For(); + _issueManager = new IssueManager(_fakeRepo); + _issue = new Issue(); + } + + [Fact] + public async Task Should_Assign_An_Issue_To_A_User() + { + // Arrange + _fakeRepo.GetIssueCountOfUserAsync(_userId).Returns(1); + + // Act + await _issueManager.AssignToUserAsync(_issue, _userId); + + //Assert + _issue.AssignedUserId.ShouldBe(_userId); + await _fakeRepo.Received(1).GetIssueCountOfUserAsync(_userId); + } + + [Fact] + public async Task Should_Not_Allow_To_Assign_Issues_Over_The_Limit() + { + // Arrange + _fakeRepo + .GetIssueCountOfUserAsync(_userId) + .Returns(IssueManager.MaxAllowedOpenIssueCountForAUser); + + // Act & Assert + await Assert.ThrowsAsync(async () => + { + await _issueManager.AssignToUserAsync(_issue, _userId); + }); + + _issue.AssignedUserId.ShouldBeNull(); + await _fakeRepo.Received(1).GetIssueCountOfUserAsync(_userId); + } + } +} +```` + +> Keep your test code clean to create a maintainable test suite. + ## Integration Tests TODO