From 37277945b03beaa6e8c7727ec04cac03f6ac58cd Mon Sep 17 00:00:00 2001 From: Shaun Chong Date: Sat, 14 Dec 2024 15:48:24 +0800 Subject: [PATCH] test: Fix tests --- .../Features/Calculator.feature.cs | 30 ++-- .../DataBuilders/LinkDataBuilder.cs | 2 +- .../ArticleApiModelDataBuilder.cs | 145 ++++++++++++++++++ .../Controllers/ArticleControllerTests.cs | 20 ++- .../Steps/ArticleControllerSteps.cs | 19 +++ 5 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 src/Linker.WebApi.UnitTests/ArticleApiModelDataBuilder.cs diff --git a/src/Linker.Data.UnitTests.SpecFlow/Features/Calculator.feature.cs b/src/Linker.Data.UnitTests.SpecFlow/Features/Calculator.feature.cs index 4910989..385dd28 100644 --- a/src/Linker.Data.UnitTests.SpecFlow/Features/Calculator.feature.cs +++ b/src/Linker.Data.UnitTests.SpecFlow/Features/Calculator.feature.cs @@ -24,7 +24,7 @@ public partial class CalculatorFeature : object, Xunit.IClassFixture(_testOutputHelper); } - public virtual void ScenarioStart() + public void ScenarioStart() { testRunner.OnScenarioStart(); } - public virtual void ScenarioCleanup() + public void ScenarioCleanup() { testRunner.CollectScenarioErrors(); } @@ -88,26 +88,16 @@ void System.IDisposable.Dispose() [Xunit.TraitAttribute("FeatureTitle", "Calculator")] [Xunit.TraitAttribute("Description", "Add two numbers")] [Xunit.TraitAttribute("Category", "mytag")] - public virtual void AddTwoNumbers() + public void AddTwoNumbers() { string[] tagsOfScenario = new string[] { "mytag"}; System.Collections.Specialized.OrderedDictionary argumentsOfScenario = new System.Collections.Specialized.OrderedDictionary(); - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Add two numbers", null, tagsOfScenario, argumentsOfScenario, this._featureTags); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Add two numbers", null, tagsOfScenario, argumentsOfScenario, featureTags); #line 9 this.ScenarioInitialize(scenarioInfo); #line hidden - bool isScenarioIgnored = default(bool); - bool isFeatureIgnored = default(bool); - if ((tagsOfScenario != null)) - { - isScenarioIgnored = tagsOfScenario.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((this._featureTags != null)) - { - isFeatureIgnored = this._featureTags.Where(__entry => __entry != null).Where(__entry => String.Equals(__entry, "ignore", StringComparison.CurrentCultureIgnoreCase)).Any(); - } - if ((isScenarioIgnored || isFeatureIgnored)) + if ((TagHelper.ContainsIgnoreTag(tagsOfScenario) || TagHelper.ContainsIgnoreTag(featureTags))) { testRunner.SkipScenario(); } diff --git a/src/Linker.TestCore/DataBuilders/LinkDataBuilder.cs b/src/Linker.TestCore/DataBuilders/LinkDataBuilder.cs index 5712181..4bb0116 100644 --- a/src/Linker.TestCore/DataBuilders/LinkDataBuilder.cs +++ b/src/Linker.TestCore/DataBuilders/LinkDataBuilder.cs @@ -25,7 +25,7 @@ public sealed class LinkDataBuilder : ITestDataBuilder private string? country; private string? keyPersonName; private Grammar grammar; - private Visibility visibility; + private Visibility visibility = Visibility.Public; private DateTime createdAt = DateTime.Now; private DateTime modifiedAt = DateTime.Now; diff --git a/src/Linker.WebApi.UnitTests/ArticleApiModelDataBuilder.cs b/src/Linker.WebApi.UnitTests/ArticleApiModelDataBuilder.cs new file mode 100644 index 0000000..a5f07c2 --- /dev/null +++ b/src/Linker.WebApi.UnitTests/ArticleApiModelDataBuilder.cs @@ -0,0 +1,145 @@ +namespace Linker.WebApi.UnitTests; + +using Linker.WebApi.ApiModels; +using System; +using System.Collections.Generic; + +public sealed class ArticleApiModelDataBuilder +{ + private string id = Guid.NewGuid().ToString(); + private string url = "https://google.com"; + private string category = "Education"; + private string description = "hello world"; + private IEnumerable tags = new List() { "tag1", "tag2" }; + private string language = "en"; + private DateTime lastVisitAt = DateTime.Now; + private DateTime createdAt = DateTime.Now; + private DateTime modifiedAt = DateTime.Now; + private string createdBy = Guid.NewGuid().ToString(); + + private string title = "title"; + private string author = "Author"; + private int year = 2004; + private bool watchLater; + private string domain = "google.com"; + private string grammar = "Normal"; + + public ArticleApiModelDataBuilder WithId(string value) + { + this.id = value; + return this; + } + + public ArticleApiModelDataBuilder WithUrl(string value) + { + this.url = value; + return this; + } + + public ArticleApiModelDataBuilder WithCategory(string value) + { + this.category = value; + return this; + } + + public ArticleApiModelDataBuilder WithDescription(string value) + { + this.description = value; + return this; + } + + public ArticleApiModelDataBuilder WithTags(IEnumerable value) + { + this.tags = value; + return this; + } + + public ArticleApiModelDataBuilder WithLanguage(string value) + { + this.language = value; + return this; + } + + public ArticleApiModelDataBuilder WithLastVisitAt(DateTime value) + { + this.lastVisitAt = value; + return this; + } + + public ArticleApiModelDataBuilder WithCreatedAt(DateTime value) + { + this.createdAt = value; + return this; + } + + public ArticleApiModelDataBuilder WithModifiedAt(DateTime value) + { + this.modifiedAt = value; + return this; + } + + public ArticleApiModelDataBuilder WithCreatedBy(string value) + { + this.createdBy = value; + return this; + } + + public ArticleApiModelDataBuilder WithTitle(string value) + { + this.title = value; + return this; + } + + public ArticleApiModelDataBuilder WithAuthor(string value) + { + this.author = value; + return this; + } + + public ArticleApiModelDataBuilder WithYear(int value) + { + this.year = value; + return this; + } + + public ArticleApiModelDataBuilder WithWatchLater(bool value) + { + this.watchLater = value; + return this; + } + + public ArticleApiModelDataBuilder WithDomain(string value) + { + this.domain = value; + return this; + } + + public ArticleApiModelDataBuilder WithGrammar(string value) + { + this.grammar = value; + return this; + } + + public ArticleApiModel Build() + { + return new ArticleApiModel + { + Id = this.id, + Url = this.url, + Category = this.category, + Description = this.description, + Tags = this.tags, + Language = this.language, + LastVisitAt = this.lastVisitAt, + CreatedAt = this.createdAt, + ModifiedAt = this.modifiedAt, + CreatedBy = this.createdBy, + Title = this.title, + Author = this.author, + Year = this.year, + WatchLater = this.watchLater, + Domain = this.domain, + Grammar = this.grammar, + }; + } +} diff --git a/src/Linker.WebApi.UnitTests/Controllers/ArticleControllerTests.cs b/src/Linker.WebApi.UnitTests/Controllers/ArticleControllerTests.cs index 186d8f5..f6530be 100644 --- a/src/Linker.WebApi.UnitTests/Controllers/ArticleControllerTests.cs +++ b/src/Linker.WebApi.UnitTests/Controllers/ArticleControllerTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Linker.Core.Models; using Linker.TestCore.DataBuilders; + using Linker.WebApi.ApiModels; using Linker.WebApi.UnitTests.Steps; using Microsoft.AspNetCore.Mvc; using Xunit; @@ -101,15 +102,23 @@ public async Task GetAllAsync_HavingResults_ReturnResults() new ArticleDataBuilder().Build(), }; + var articleApiModels = new List + { + new ArticleApiModelDataBuilder().Build(), + new ArticleApiModelDataBuilder().Build(), + }; + this.steps - .GivenRepoGetAllAsyncReturns(articles); + .GivenRepoGetAllAsyncReturns(articles) + .GivenMapperMapToArticleApiModelReturns(articleApiModels); await this.steps.WhenIGetAllAsync(); this.steps .ThenIExpectNoExceptionIsThrown() .ThenIExpectRepoGetAllAsyncToBeCalled(1) - .ThenIExpectResultToBe(new OkObjectResult(articles)); + .ThenIExpectMapperToBeCalledWithArticle(2) + .ThenIExpectResultToBe(new OkObjectResult(articleApiModels)); } [Fact] @@ -118,16 +127,19 @@ public async Task GetByIdAsync_FoundRecord_ReturnResult() var guidStr = "ba3e784b-5edd-432d-a6fb-5215c27d83d2"; var guid = Guid.Parse(guidStr); var article = new ArticleDataBuilder().WithId(guidStr).Build(); + var articleApiModel = new ArticleApiModelDataBuilder().WithId(guidStr).Build(); this.steps - .GivenRepoGetByIdAsyncReturns(article); + .GivenRepoGetByIdAsyncReturns(article) + .GivenMapperMapToArticleApiModelReturns([articleApiModel]); await this.steps.WhenIGetByIdAsync(guid); this.steps .ThenIExpectNoExceptionIsThrown() .ThenIExpectRepoGetByIdAsyncToBeCalledWith(guidStr, 1) - .ThenIExpectResultToBe(new OkObjectResult(article)); + .ThenIExpectMapperToBeCalledWithArticle(1) + .ThenIExpectResultToBe(new OkObjectResult(articleApiModel)); } [Fact] diff --git a/src/Linker.WebApi.UnitTests/Steps/ArticleControllerSteps.cs b/src/Linker.WebApi.UnitTests/Steps/ArticleControllerSteps.cs index 52aca08..88340b5 100644 --- a/src/Linker.WebApi.UnitTests/Steps/ArticleControllerSteps.cs +++ b/src/Linker.WebApi.UnitTests/Steps/ArticleControllerSteps.cs @@ -10,6 +10,7 @@ using Linker.Core.Models; using Linker.Core.Repositories; using Linker.TestCore; + using Linker.WebApi.ApiModels; using Linker.WebApi.Controllers; using Microsoft.AspNetCore.Http; @@ -125,6 +126,16 @@ public ArticleControllerSteps GivenRepoGetAllAsyncReturns(IEnumerable
a return this; } + public ArticleControllerSteps GivenMapperMapToArticleApiModelReturns(IEnumerable apiModels) + { + this.mockMapper + .SetupSequence(x => x.Map(It.IsAny
())) + .Returns(apiModels.First()) + .Returns(apiModels.Last()); + + return this; + } + public ArticleControllerSteps GivenRepoGetByIdAsyncReturns(Article article) { this.mockRepository @@ -213,6 +224,14 @@ public Task WhenIUpdateAsync(Guid id, UpdateArticleRequest request) #region Then + public ArticleControllerSteps ThenIExpectMapperToBeCalledWithArticle(int times) + { + this.mockMapper + .Verify(x => x.Map(It.IsAny
()), Times.Exactly(times)); + + return this; + } + public ArticleControllerSteps ThenIExpectMapperToBeCalledWith(CreateArticleRequest request, int times) { this.mockMapper