Introduction
早在2005年,Martin Fowler就提出了“fluent interface“这种编码风格(link)。我们比较熟悉的LINQ就是这”fluent“风格的。
这种编码风格,使得代码表达十分流畅,更容易阅读和理解。FluentAssertions正是应用了”fluent"的编码风格的断言工具。
FluentAssertions的license是Apache License 2.0(link)。它支持.NET Framework 4.7+以及.NET Core 2.1+,以及MSTest2、xUnit、NUnit等测试框架。
下面我们来看下,FluentAssertions能如何帮到我们。
Let’s coding
把FluentAssertions加到我们的工程中十分简单,只需要通过NuGet安装。
官网给的第一个例子就十分体现出”fluent“的含义。
using FluentAssertions;
using Xunit;
namespace Comparison
{
public class UnitTest
{
[Fact]
public void Test_Simple_Example()
{
string actual = "ABCDEFGHI";
actual.Should().StartWith("AB").And.EndWith("HI").And.Contain("EF").And.HaveLength(9);
}
}
}
下面是不用FluentAssertions的同一个测试代码
using Xunit;
namespace Comparison
{
public class UnitTest
{
[Fact]
public void Test_Simple_Example()
{
string actual = "ABCDEFGHI";
Assert.StartsWith("AB", actual);
Assert.EndsWith("HI", actual);
Assert.Contains("EF", actual);
Assert.Equal(10, actual.Length);
}
}
}
简洁和表意程度,前后对比,一目了然。
并且你可以将多个断言打包在一个AssertionScope里
[Fact]
public void Test_AssertScope() {
using (new AssertionScope()) {
5.Should().Be(10);
"Actual".Should().Be("Expected");
}
}
这样的话,scope里的所有失败都会被打印出来。
Xunit.Sdk.XunitException
Expected value to be 10, but found 5.
Expected string to be "Expected" with a length of 8, but "Actual" has a length of 6, differs near "Act" (index 0).
at FluentAssertions.Execution.XUnit2TestFramework.Throw(String message)
at FluentAssertions.Execution.TestFrameworkProvider.Throw(String message)
at ...
一些很有特点的用法
运行时间
Action someAction = () => Thread.Sleep(100);
someAction.ExecutionTime().Should().BeLessThanOrEqualTo(200.Milliseconds());
对于Task
Func<Task> someAsyncWork = () => SomethingReturningATask();
await someAsyncWork.Should().CompleteWithinAsync(100.Milliseconds());
// 包括对返回值的检查
Func<Task<int>> someAsyncFunc;
await someAsyncFunc.Should().CompleteWithinAsync(100.Milliseconds()).WithResult(42);
浮点数精度
float value = 3.1415927F;
value.Should().BeApproximately(3.14F, 0.01F);
GUID
Guid theGuid = Guid.NewGuid();
Guid sameGuid = theGuid;
Guid otherGuid = Guid.NewGuid();
theGuid.Should().Be(sameGuid);
theGuid.Should().NotBe(otherGuid);
还有其他很多有特点的断言,大家可以去看官网文档。
以上是对FluentAssertions的一个简单介绍,希望能够帮助大家写出更好的单元测试。
(end.)