Unit Test 基础
xUnit
Official Website
Tutorials (Chinese)
https://www.cnblogs.com/NorthAlan/tag/xUnit/
Shared Context between Tests
https://xunit.net/docs/shared-context
Moq
nuget: Moq
Quick Start
https://github.com/moq/moq4/wiki/Quickstart
Working With SetupGet, VerifyGet, SetupSet, VerifySet, SetupProperty
Mock EF
Testing with a mocking framework - EF6 | Microsoft Learn
Mock methods in the same class
[Solved] Using Moq to mock only some methods | 9to5Answer
对于私有方法的测试可利用反射机制。
Unit Test
Best Practice
https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
1.DB
MemoryDatabase
Nuget: Microsoft.EntityFrameworkCore.InMemory
var optionsQuickOrderDb = new DbContextOptionsBuilder<QuickOrder.Entity.DataContext>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
QuickOrder.Entity.DataContext mockQuickOrderContext = new QuickOrder.Entity.DataContext(optionsQuickOrderDb);
Guid.NewGuid().ToString()为内存数据库名称,相同名称的数据库可共享数据,有时候会带来便利,但应注意Test方法执行顺序带来的问题。
2. File System
Moq
var fileMock = new Mock
//Setup mock file using a memory stream
var content = "Hello World from a Fake File";
var fileName = "test.txt";
using (var ms = new MemoryStream())
{
using (var writer = new StreamWriter(ms))
{
writer.Write(content);
writer.Flush();
ms.Position = 0;
fileMock.Setup(_ => .OpenReadStream()).Returns(ms);
fileMock.Setup( => .FileName).Returns(fileName);
fileMock.Setup( => _.Length).Returns(ms.Length);
}
}
System.IO.Abstractions
Nuget: System.IO.Abstractions, System.IO.Abstractions.TestingHelpers
MockFileSystem mockFileSystem = new MockFileSystem();List<KeyValuePair<string,string>> source = new List<KeyValuePair<string, string>>() { new KeyValuePair<string, string>("readme.txt", "Information about this package."), new KeyValuePair<string, string>("test.txt","Hello World from a Fake File.") };
using (var ms = new MemoryStream())
{
using (ZipOutputStream zipOutputStream = new ZipOutputStream(ms))
{
zipOutputStream.SetLevel(1);
foreach (var item in source)
{
byte[] byteContent = Encoding.UTF8.GetBytes(item.Value);
ZipEntry entry = new ZipEntry(item.Key);
entry.DateTime = DateTime.Now;
zipOutputStream.PutNextEntry(entry);
zipOutputStream.Write(byteContent, 0, byteContent.Length);
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
var mockInputFile = new MockFileData(ms.ToArray());
mockFileSystem.AddFile(@"C:\temp\test.zip", mockInputFile);
}
ZipHelper.RecursiveDecompress(mockFileSystem, @"C:\temp\test.zip", @"C:\temp", true, true);
MockFileData readmeTxtFile = mockFileSystem.GetFile(@"C:\temp\test\readme.txt");
MockFileData testTxtFile = mockFileSystem.GetFile(@"C:\temp\test\test.txt");
Assert.NotNull(readmeTxtFile);
Assert.NotNull(testTxtFile);
3. Redis & RabbitMQ
var mockRedisRepository = new Mock
mockRedisRepository.Setup(mock => mock.GetNewEntityId(EntityIdNameSpace.Request, userModel.UserName)).Returns(300001);
4. External Api
var mockExternalApiService = new Mock
List
{
new WOLProject(){ Id = new Guid("a9587e09-644a-04ba-b571-39ffd284cf5a"), Text = "Enterprise_Project_01", ProjectId = "enterprise003" },
new WOLProject(){ Id = new Guid("d019dc1d-0d69-402a-20bc-39ffd2856e2a"), Text = "Enterprise_Project_02", ProjectId = "enterprise004" }
};
mockExternalApiService.Setup(mock => mock.GetEnterpriseProjectInfo(mockIHttpContextAccessor.Object).Result).Returns(wolProjects);
5. UserModel
Create a UserModel directly using claims
string userGuid = "07CD07F2-CBE0-DE1E-31F2-39FFCE2B68AF";
string userName = "demo1@qq.com";
string displayName = "demo1 DEV";
var claims = new List
{
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", userGuid, "http://www.w3.org/2001/XMLSchema#string", "urn:jonckersauthserver"),
new Claim("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", userName, "http://www.w3.org/2001/XMLSchema#string", "urn:jonckersauthserver"),
new Claim("displayName", displayName, "http://www.w3.org/2001/XMLSchema#string", "urn:jonckersauthserver"),
new Claim("companyGuid", Guid.Empty.ToString(), "http://www.w3.org/2001/XMLSchema#string", "urn:jonckersauthserver")
};
ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, "Service", "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", "http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
UserModel userModel = new UserModel(claimsPrincipal);
6.IConfiguration
Var inMemorySettings = new Dictionary<string, string> {
{"TopLevelKey", "TopLevelValue"},
{"SectionName:SomeKey", "SectionValue"},
//...populate as needed for the test};
IConfiguration configuration = new ConfigurationBuilder()
.AddInMemoryCollection(inMemorySettings)
.Build();
From https://stackoverflow.com/questions/64794219/how-to-mock-iconfiguration-getvalue