Unit Test 基础

发布时间 2023-07-10 15:04:38作者: 【唐】三三

xUnit

Official Website

https://xunit.net/

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

https://hamidmosalla.com/2017/08/03/moq-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方法执行顺序带来的问题。

  • WordsOnIine.CIient.WebApi.v4.Domain
    • Dependencies
    AutoMapper
    Configs
    E nums
    Exceptions
    Extensions
    Helper
    I Reposito
    C* IProjectLanguageRepository.cs
    a c* RedisRepository.cs
    a c* Repository.cs
    a c* RequestRepository.cs
    a c* UnitOfWork.cs
    IService
    a Messages
    Models
    Repositories
    OrderRepository.cs
    ProjectLanguageRepository.cs
    RedisRepository.cs
    RequestRepository.cs

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 wolProjects = new 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