# Unittest 程式筆記 ###### tags: `C#` `待更新` ## C# "internal" access modifier when doing unit testing??? https://stackoverflow.com/questions/358196/c-sharp-internal-access-modifier-when-doing-unit-testing https://dotblogs.com.tw/hatelove/2012/11/09/learning-tdd-in-30-days-day4-why-you-should-not-write-unit-test-with-private-and-protected-method ## NSubstitute [NSubstitute 官方文件](https://nsubstitute.github.io/) [NSubstitute 基本介紹-3](https://ithelp.ithome.com.tw/articles/10267165) ```csharp //Create: var calculator = Substitute.For<ICalculator>(); //Set a return value: calculator.Add(1, 2).Returns(3); Assert.AreEqual(3, calculator.Add(1, 2)); //Check received calls: calculator.Received().Add(1, Arg.Any<int>()); calculator.DidNotReceive().Add(2, 2); //Raise events calculator.PoweringUp += Raise.Event(); ``` ### exception [Throwing exceptions 官方文件](https://nsubstitute.github.io/help/throwing-exceptions/) [NSubstitute - make async method (Task) throw an exception](https://blog.krusen.dk/nsubstitute-make-async-method-throw) ```csharp //For non-voids: calculator.Add(-1, -1).Returns(x => { throw new Exception(); }); //For voids and non-voids: calculator .When(x => x.Add(-2, -2)) .Do(x => { throw new Exception(); }); Assert.Throws<Exception>(() => calculator.Add(-1, -1)); var exception = Assert.ThrowsAsync<Exception>(() => calculator.AddAsync(-2, -2)); ``` ### Received ```csharp! _accountService.Received().GetAccount("AccountId")); _accountService.Received().AccountFolter(Arg.Any<AccountFilterRequest>())); //也可以測物件內部的值 _accountService.Received().AccountFolter(Arg.Is<AccountFilterRequest>(x=> x.country == "TW" && x.Age < 18 && IsAddressInfo(x.AddressInfo, "Taipei", "road")))); //received could use ToExpectedObject check sub object private bool IsAddressInfo(AddressInfo addressInfo, string country, string road) { var expectedObject = new {Country = country,Road = road}.ToExpectedObject(); return expectedObject.Matches(addressInfo); } ``` #### 相關文件 [Argument matchers 官方文件](https://nsubstitute.github.io/help/argument-matchers/) [NSubstitute with object as parameter in Received call](https://stackoverflow.com/a/14582094/19304838) ## ExpectedObjects nuget package install ExpectedObjects 目前版本 collection 是不關心順序的,若順序是重要的可以在創建 ToExpectedObjects 時設置 ```csharp var expected = new TypeWithIEnumerable { Objects = new List<string> {"test2", "test1"} }.ToExpectedObject(ctx => ctx.UseOrdinalComparison()); ``` [Compare Object Equality](https://dotblogs.com.tw/hatelove/2016/03/28/compare-object-equality-with-expected-objects) [Collections](https://github.com/derekgreer/expectedObjects/wiki/Collections) [expectedObjects gitlab](https://github.com/derekgreer/expectedObjects) ## ModelState.IsValid unitest 不會檢查??? 目前測起來是這樣 ## test IActionResult Method ```csharp [Test] public void Create() { var actionResult = new TestPlayerController(testPlayerService).Create(new CreateTestPlayerDto()); var okResult = actionResult as OkObjectResult; Assert.AreEqual("OK", okResult?.Value); Assert.IsTrue(okResult.Value is string); Assert.AreEqual(200, okResult?.StatusCode); } ``` [Unit testing controller methods which return IActionResult](https://stackoverflow.com/questions/41292919/unit-testing-controller-methods-which-return-iactionresult) [Unit test controller logic in ASP.NET Core](https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/testing?view=aspnetcore-7.0) ## ILogger in unit test ### 法一: mock ILogger ```csharp public void Setup() { var logger = Substitute.For<ILogger<TargetController>>(); _targetController = new TargetController(logger); } ``` ### 法二: LoggerFactory create console log ```csharp public void Setup() { using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); var logger = loggerFactory.CreateLogger<TargetController>(); _targetController = new TargetController(logger); } ``` ### 法三: Replace ILogger with NullLogger ```csharp public void Setup() { var logger = new NullLogger<TargetController>(); _targetController = new TargetController(logger); } ``` ### 相關文章 [Unit Testing with `ILogger<T>`](https://www.cnblogs.com/microestc/p/14202882.html) ## Unit Test and Mock Automapper ASP.NET Core ???(待更新) [Unit Test and Mock Automapper ASP.NET Core](https://www.thecodebuzz.com/unit-test-mock-automapper-asp-net-core-imapper/)