# 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/)