单元测试只专注于测试一个类或方法
每个测试用例由Arrange(测试数据)、Act(执行被测试方法)、Assert(断言,actual == expected?)
单元测试的命名规范:项目名/命名空间/类名+Tests
被测试的类的对应变量名一般叫sut(System Under Test)
没有参数的TestCase标注[Fact];
C#
/// <summary>
/// 给定两个数 计算结果要正确
/// </summary>
[Fact]
public void Test1()
{
//Arrange
int a = 1;
int b = 2;
//Act
Cash sut = new();
int sutResult = sut.add(a,b);
//Assert
int expectedResult = 3;
Assert.Equal(expectedResult, sutResult);
}
有参数的TestCase标注[Theory],然后使用[InlineData]等来提供测试数据。
C#
/// <summary>
/// 给定两个数 相除结果要正确
/// </summary>
[Theory]
[InlineData(2,1,2)]
[InlineData(10,2,5)]
public void Test2(int i ,int j,decimal result)
{
//Arrange
//Act
Cash sut = new();
decimal sutResult = sut.except(i, j);
//Assert
Assert.Equal(result, sutResult);
}
使用AutoFixture+AutoFakeItEasy+FluentAssertions作为测试Fake和Assertions
安装Nuget:AutoFixture.AutoFakeItEasy、AutoFixture.Xunit2、FluentAssertions三个Nuget包。
安装成功后,配置AutoFakeItEasy的AutoDataAttribute
C#
public class AutoFakeItEasyAttribute: AutoDataAttribute
{
//AutoFakeItEasyCustomization can create implementation of interfaces and abstract classes using FakeItEasy
public AutoFakeItEasyAttribute()
: base(CreateFixture)
{
}
private static IFixture CreateFixture()
{
Fixture fixture = new Fixture();
fixture.Customize(new AutoFixture.AutoFakeItEasy.AutoFakeItEasyCustomization());
fixture.Customizations.Add(new CancellationTokenGenerator());
fixture.Behaviors.Add(new OmitOnRecursionBehavior());
return fixture;
}
}
使用AutoFakeItEasy,贴上标签就行:
C#
[Theory]
[AutoFakeItEasy]
public async Task CreateUserASuccessfully(
[Frozen] IUserRepository userRepository,
UserService sut,
string email, string password,
CancellationToken cancellationToken)
{
//Arrange
A.CallTo(() => userRepository.GetByEmailAsync(email, cancellationToken))
.Returns((User?)null);
//Act
Guid userId = await sut.CreateUserAsync(email, password, cancellationToken);
//Assert
userId.Should().NotBeEmpty();
A.CallTo(() => userRepository.InsertAsync(A<User>.That.Matches(u=>u.Email==email&&u.ValidatePassword(password)), cancellationToken))
.MustHaveHappenedOnceExactly();
}