You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xUnitStudy/xUnitStudy.WebApi.Test/UseXUnitAssertTest.cs

709 lines
22 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using xUnitStudy.Model;
namespace xUnitStudy.WebApi.Test
{
/// <summary>
/// https://xunit.github.io/docs/comparisons
/// </summary>
[Trait("测试断言分组", "默认组")]
public class UseXUnitAssertTest : IDisposable
{
#region 准备
public UseXUnitAssertTest()
{
}
#endregion
#region Equal
[Fact]
public void Equal_String_Test()
{
Assert.Equal("ping", "ping");
}
/// <summary>
/// 断言 string 相等
/// 设置大小写、行尾符、空白符号 比较选项
/// </summary>
[Fact]
public void Equal_String_Ignore_Test()
{
//ignoreCase:忽略字符大小写差异.如果为true,比较时忽略字符大小写
Assert.Equal("ABcdEF", "abcdef", ignoreCase: true);
//ignoreLineEndingDifferences忽略行尾结束符差异。设置为true则将\rn、\r和\n视为等效。
Assert.Equal("One line\r\n", "one line\n", ignoreCase: true, ignoreLineEndingDifferences: true);
//ignoreWhiteSpaceDifferences忽略"空白"(空格、Tab)差异。设置为true则将空格和制表符以任何非零量视为等效。
Assert.Equal("One line\r", "one line\n", ignoreCase: true, ignoreLineEndingDifferences: true, ignoreWhiteSpaceDifferences: true);
}
[Fact]
public void Equal_Double_Test()
{
//注意:先舍入,然后再比较
//舍入规则:四舍五入
//精度范围[0,15]位小数
Assert.Equal(1.14d, 1.11d, precision: 1);
Assert.Equal(1.15d, 1.19d, precision: 1);
Assert //1.14d 约等于1.1 而1.15d 约等于1.2 所以不相等
.NotEqual(1.14d, 1.15d, precision: 1);
//四舍五入到2位小数精度相等
Assert.Equal(2.123d, 2.124d, 2);
//四舍五入到3位小数精度相等
Assert.Equal(3.1234d, 3.1231d, 3);
//四舍五入到4位小数精度不等
Assert.NotEqual(3.12345d, 3.12349d, 4);
//四舍五入到整数,相等
Assert.Equal(15d, 15.111d, precision: 0);
//没有小数位,四舍五入到整数
Assert.Equal(15d, 15d, precision: 0);
}
[Fact]
public void Equal_Decimal_Test()
{
//注意:先舍入,然后再比较
//舍入规则:四舍五入
//精度范围[0,15]位小数
Assert.Equal(1.14M, 1.11M, precision: 1);
Assert.Equal(1.15M, 1.19M, precision: 1);
Assert //1.14M 约等于1.1 而1.15M 约等于1.2 所以不相等
.NotEqual(1.14M, 1.15M, precision: 1);
//四舍五入到2位小数精度相等
Assert.Equal(2.123M, 2.124M, 2);
//四舍五入到3位小数精度相等
Assert.Equal(3.1234M, 3.1231M, 3);
//四舍五入到4位小数精度不等
Assert.NotEqual(3.12345M, 3.12349M, 4);
//四舍五入到整数,相等
Assert.Equal(15M, 15.111M, precision: 0);
//没有小数位,四舍五入到整数
Assert.Equal(15M, 15M, precision: 0);
}
[Fact]
public void Equal_Datetime_Test()
{
Assert.Equal(DateTime.Now, DateTime.Now.AddSeconds(1), TimeSpan.FromSeconds(2));
Assert.Equal(DateTime.Now, DateTime.Now.AddMinutes(1), TimeSpan.FromMinutes(2));
}
/// <summary>
/// Equal 泛型版本
/// 泛型版基本上都有简化写法
/// </summary>
[Fact]
public void Equal_Generic_T_Test()
{
//形如Assert.Equal<T>(Expected T, Actual T);
//常见类型都可以简化,或是有更好的非泛型版,此时,一般用非泛型版
Assert.Equal<string>("ping", "ping");
Assert //基本使用非泛型版本
.Equal("ping", "ping");
Assert.Equal<int>(3, 3);
Assert //简化为
.Equal(3, 3);
Assert.Equal<long>(3L, 3L);
Assert //简化为
.Equal(3L, 3L);
Assert.Equal<double>(5.5d, 5.5d);
Assert //简化为
.Equal(5.5d, 5.5d);
Assert.Equal<decimal>(5.5M, 5.5M);
Assert //简化为
.Equal(5.5M, 5.5M);
Assert.Equal<DateTime>(DateTime.Now.Date, DateTime.Now.Date);
Assert //简化为
.Equal(DateTime.Now.Date, DateTime.Now.Date);
//类或其它自定义结构比较,可以使用
var obj = new object();
Assert.Equal<object>(obj, obj);
Assert //简化为
.Equal(obj, obj);
}
/// <summary>
/// Equal 实现了IEqualityComparer接口的泛型版本
/// </summary>
[Fact]
public void Equal_Generic_IEqualityComparer_Test()
{
//形如Assert.Equal<T>(Expected T, Actual T,IEqualityComparer comparer);
//实现 IEqualityComparer 接口
var expected = new AssertEqualDemo() { Id = 1, Name = "zhansan" };
var actual = new AssertEqualDemo() { Id = 1, Name = "lisi" };
//实现 IEqualityComparer 接口的,可以是被比较对象自己实现接口,也可以是单独的类。
var comparer = new AssertEqualDemo();
Assert.Equal<AssertEqualDemo>(expected, actual, comparer);
Assert.//可以简写为
Equal(expected, actual, comparer);
//id不一样则不相等
expected.Id = 3;
Assert.NotEqual(expected, actual, comparer);
}
/// <summary>
/// 实现IEnumerable接口对象的 Equal比较
/// </summary>
[Fact]
public void Equal_Generic_IEnumerable_Test()
{
//对实现IEnumerable接口的对象进行 Equal比较
//形如Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual)
List<string> expected = new List<string>() { "first", "second" };
List<string> actual = new List<string>() { "first", "second" };
Assert.Equal<List<string>>(expected, actual);
Assert.//简写为
Equal(expected, actual);
}
/// <summary>
/// 实现IEnumerable接口对象的 Equal 比较
/// 传入实现IEqualityComparer接口的比较器
/// </summary>
[Fact]
public void Equal_Generic_IEnumerable_IEqualityComparer_Test()
{
//对实现IEnumerable接口的对象进行 Equal比较
//形如Equal<T>(IEnumerable<T> expected, IEnumerable<T> actualIEqualityComparer comparer)
//传入实现了 IEqualityComparer 接口的比较参数
var expected = new List<AssertEqualDemo>()
{
new AssertEqualDemo() { Id = 1, Name = "zhansan" },
new AssertEqualDemo() { Id = 2, Name = "lis" },
};
var actual = new List<AssertEqualDemo>()
{
new AssertEqualDemo() { Id = 1, Name = "wangwu" },
new AssertEqualDemo() { Id = 2, Name = "zhaoliu" },
};
//实现 IEqualityComparer 接口的,可以是被比较对象自己实现接口,也可以是单独的类。
var comparer = new AssertEqualDemo();
Assert.Equal<AssertEqualDemo>(expected, actual, comparer);
Assert.//可以简写为
Equal(expected, actual, comparer);
//id不一样则不相等
expected[0].Id = 100;
Assert.NotEqual(expected, actual, comparer);
}
#endregion
#region NotEqual
[Fact]
public void NotEqual_String_Test()
{
Assert.NotEqual("ping", "ack");
}
[Fact]
public void NotEqual_Double_Test()
{
//注意:先舍入,然后再比较
//舍入规则:四舍五入
//精度范围[0,15]位小数
Assert //1.14d 约等于1.1 而1.15d 约等于1.2 所以不相等
.NotEqual(1.14d, 1.15d, precision: 1);
//舍入到2位小数精度相等
Assert.NotEqual(2.124d, 2.126d, 2);
//舍入到3位小数精度相等
Assert.NotEqual(3.1234d, 3.1239d, 3);
//舍入到4位小数精度不等
Assert.NotEqual(3.12346d, 3.12341d, 4);
//舍入到整数,相等
Assert.NotEqual(16d, 15.111d, precision: 0);
//没有小数位,舍入到整数
Assert.NotEqual(16d, 160d, precision: 0);
}
[Fact]
public void NotEqual_Decimal_Test()
{
//注意:先舍入,然后再比较
//舍入规则:四舍五入
//精度范围[0,15]位小数
Assert //1.14M 约等于1.1 而1.15M 约等于1.2 所以不相等
.NotEqual(1.14M, 1.15M, precision: 1);
//四舍五入到2位小数精度不等
Assert.NotEqual(2.123M, 2.129M, 2);
//四舍五入到3位小数精度不等
Assert.NotEqual(3.1234M, 3.1236M, 3);
//四舍五入到4位小数精度不等
Assert.NotEqual(3.12345M, 3.12349M, 4);
//四舍五入到整数,不等
Assert.NotEqual(15M, 15.501M, precision: 0);
//没有小数位,四舍五入到整数
Assert.NotEqual(29M, 15M, precision: 0);
}
[Fact]
public void NotEqual_Generic_T_Test()
{
//形如Assert.NotEqual<T>(Expected T, Actual T);
Assert.NotEqual<string>("ping", "ack");
Assert //基本使用非泛型版本
.NotEqual("ping", "ack");
Assert.NotEqual<int>(3, 4);
Assert //简化为
.NotEqual(3, 4);
Assert.NotEqual<long>(3L, 4L);
Assert //简化为
.NotEqual(3L, 4L);
Assert.NotEqual<double>(5.5d, 6.5d);
Assert //简化为
.NotEqual(5.5d, 6.5d);
Assert.NotEqual<decimal>(5.5M, 5.6M);
Assert //简化为
.NotEqual(5.5M, 6.5M);
Assert.NotEqual<DateTime>(DateTime.Now.Date, DateTime.Now.Date.AddDays(1));
Assert //简化为
.NotEqual(DateTime.Now.Date, DateTime.Now.Date.AddDays(1));
//类或其它自定义结构比较,可以使用
var obj = new object();
var obj2 = new object();
Assert.NotEqual<object>(obj, obj2);
Assert //简化为
.NotEqual(obj, obj2);
}
[Fact]
public void NotEqual_Generic_IEqualityComparer_Test()
{
//形如Assert.NotEqual<T>(Expected T, Actual T,IEqualityComparer comparer);
//实现 IEqualityComparer 接口
var expected = new AssertEqualDemo() { Id = 1, Name = "zhansan" };
var actual = new AssertEqualDemo() { Id = 1, Name = "lishi" };
//实现 IEqualityComparer 接口的,可以是被比较对象自己实现接口,也可以是单独的类。
var comparer = new AssertEqualDemo();
Assert.Equal<AssertEqualDemo>(expected, actual, comparer);
Assert.//可以简写为
Equal(expected, actual, comparer);
//id不一样则不相等
expected.Id = 3;
Assert.NotEqual(expected, actual, comparer);
}
[Fact]
public void NotEqual_Generic_IEnumerable_Test()
{
//对实现IEnumerable接口的对象进行 Equal比较
//形如NotEqual<T>(IEnumerable<T> expected, IEnumerable<T> actual)
List<string> expected = new List<string>() { "first", "second","third" };
List<string> actual = new List<string>() { "first", "second" };
Assert.NotEqual<List<string>>(expected, actual);
Assert.//简写为
NotEqual(expected, actual);
}
[Fact]
public void NotEqual_Generic_IEnumerable_IEqualityComparer_Test()
{
//对实现IEnumerable接口的对象进行 Equal比较
//形如NotEqual<T>(IEnumerable<T> expected, IEnumerable<T> actualIEqualityComparer comparer)
//传入实现了 IEqualityComparer 接口的比较参数
var expected = new List<AssertEqualDemo>()
{
new AssertEqualDemo() { Id = 1, Name = "zhansan" },
new AssertEqualDemo() { Id = 2, Name = "lis" },
};
var actual = new List<AssertEqualDemo>()
{
new AssertEqualDemo() { Id = 1, Name = "wangwu" },
new AssertEqualDemo() { Id = 2, Name = "zhaoliu" },
};
//实现 IEqualityComparer 接口的,可以是被比较对象自己实现接口,也可以是单独的类。
var comparer = new AssertEqualDemo();
Assert.Equal<AssertEqualDemo>(expected, actual, comparer);
Assert.//可以简写为
Equal(expected, actual, comparer);
//id不一样则不相等
expected[0].Id = 100;
Assert.NotEqual(expected, actual, comparer);
}
#endregion
#region Same
[Fact]
public void Same_String_Test()
{
//验证两个引用类型的对象,是同一个实例
//注意:必须是引用类型,不能是值类型
//特别注明sting类型虽然是引用类型但是比较特殊。采取复制策略相同值可以(不严谨的说法)认为引用相同
string expected = "hell,world!";
string actual = "hell,world!";
Assert.Same(expected, actual);
string expected2 = "hell,world!";
string actual2 = expected2;
Assert.Same(expected2, actual2);
}
[Fact]
public void Same_Object_Test()
{
object obj1 = new object();
object obj2 = new object();
object obj3 = obj1;
object obj4 = obj2;
Assert.Same(obj1, obj3);
Assert.Same(obj2, obj4);
}
[Fact]
public void Same_Class_Test()
{
object obj1 = new AssertEqualDemo() { Id = 1, Name = "zhangsan" };
object obj2 = new AssertEqualDemo() { Id = 1, Name = "zhangsan" };
object obj3 = obj1;
object obj4 = obj2;
Assert.Same(obj1, obj3);
Assert.Same(obj2, obj4);
}
#endregion
#region NotSame
[Fact]
public void NotSame_String_Test()
{
//验证两个引用类型的对象,是同一个实例
//注意:必须是引用类型,不能是值类型
//特别注明sting类型虽然是引用类型但是比较特殊。采取复制策略相同值可以(不严谨的说法)认为引用相同
string expected = "hell,world!";
string actual = "I am chinese!";
Assert.NotSame(expected, actual);
Assert.NotSame("abc", "xyz");
}
[Fact]
public void NotSame_Object_Test()
{
object obj1 = new object();
object obj2 = new object();
Object obj3 = obj2;
Assert.NotSame(obj1, obj2);
Assert.NotSame(obj1, obj3);
Assert.NotSame(new object(), new object());
}
[Fact]
public void NotSame_Class_Test()
{
object obj1 = new AssertEqualDemo() { Id = 1, Name = "zhangsan" };
object obj2 = new AssertEqualDemo() { Id = 1, Name = "zhangsan" };
object obj3 = obj1;
object obj4 = obj2;
Assert.NotSame(obj1, obj2);
Assert.NotSame(obj3, obj4);
Assert.NotSame(obj1, obj4);
Assert.NotSame(obj2, obj3);
}
#endregion
#region True
[Fact]
public void True_Condition_Test()
{
Assert.True(true);
Assert.True("ping" == "ping");
Assert.True(2 == 1 + 1);
Assert.True("ping" == "ping" && 2 == 1 + 1);
}
[Fact]
public void True_Nullable_Test()
{
bool? expected = null;
Assert.True(!expected.HasValue);
int? expected2 = null;
Assert.True(expected2 == null);
expected2 = 2;
Assert.True(2 == expected2.Value);
}
[Fact]
public void True_Message_Test()
{
Assert.True(true, "userMessage");
Assert.True("ping" == "ping", "userMessage");
Assert.True(2 == 1 + 1, "userMessage");
int? nullableInt = null;
Assert.True(null == nullableInt, "userMessage");
}
#endregion
#region False
[Fact]
public void False_Condition_Test()
{
Assert.False(false);
Assert.False("ping" == "ack");
Assert.False(3 == 1+1);
Assert.False("ping" == "ping" && 3 == 1 + 1);
}
[Fact]
public void False_Nullable_Test()
{
bool? expected = null;
Assert.False(expected.HasValue);
int? expected2 = 3;
Assert.False(expected2 == null);
Assert.False(4 == expected2.Value);
}
[Fact]
public void False_Message_Test()
{
Assert.False(false, "userMessage");
Assert.False("ping" == "ack", "userMessage");
Assert.False(2 == 1 + 3, "userMessage");
int? nullableInt = 3;
Assert.False(null == nullableInt, "userMessage");
}
#endregion
#region True|False 可替代断言
/// <summary>
/// 直接设置验证通过
/// </summary>
[Fact]
public void Pass_Test()
{
Assert.True(true, "用True断言替代");
}
[Fact]
public void Fail_Test()
{
//Assert.True(false, "用True断言替代");
}
/// <summary>
/// 大于
/// </summary>
[Fact]
public void GreaterThan_Test()
{
Assert //大于比较用True(x > y) 替代
.True(2 > 1);
int max = 5;
int min = 2;
Assert.True(max > min);
}
/// <summary>
/// 小于
/// </summary>
[Fact]
public void LessThan_Test()
{
Assert //小于比较用True(x < y) 替代
.True(2 < 3);
int max = 5;
int min = 2;
Assert.True(min < max);
}
[Fact]
public void NaN_Test()
{
//NaN=Not a Number,是否不为数字
//说明在浮点数计算中0除以0将得到NaN正数除以0将得到PositiveInfinity,负数除以0将得到NegativeInfinity。
//浮点数运算从不引发异常
Assert.True(double.IsNaN(0 / 0d));
Assert.True(double.IsPositiveInfinity(1 / 0d));
Assert.True(double.IsNegativeInfinity(-1 / 0d));
}
#endregion
[Fact]
public void Empty_Test()
{
List<string> expected = new List<string>();
Assert //针对于集合为Empty,即是集合中元素的个数为0。但集合为空引用null值时将引发异常
.Empty(expected);
}
[Fact]
public void NotEmpty_Test()
{
List<string> expected = new List<string>() { "first", "second" };
Assert //针对于集合不为Empty,即是集合中元素的个数大于0。集合为空引用null值时将引发异常
.NotEmpty(expected);
}
[Fact]
public void Null_Test()
{
Assert //null值空引用
.Null(null);
string exp = null;
Assert.Null(exp);
List<string> list = null;
Assert.Null(list);
}
[Fact]
public void NotNull_Test()
{
Assert //null值空引用
.NotNull(new object());
Assert.NotNull("");
Assert.NotNull(string.Empty);
Assert.NotNull(new List<string>());
Assert.NotNull(new List<string>() { "first", "second" });
}
[Fact]
public void IsType_Test()
{
//此形式,只在泛型不能使用时,才使用;应优先使用泛型版。
Assert.IsType(typeof(string), "aaaa");
//泛型版
Assert.IsType<string>("hell,world!");
Assert.IsType<int>(2);
Assert.IsType<long>(2L);
Assert.IsType<double>(2d);
Assert.IsType<decimal>(2M);
Assert.IsType<DateTime>(DateTime.Now);
Assert.IsType<AssertEqualDemo>(new AssertEqualDemo());
}
[Fact]
public void IsNotType_Test()
{
//此形式,只在泛型不能使用时,才使用;应优先使用泛型版。
Assert.IsNotType(typeof(string), 22);
//泛型版
Assert.IsNotType<string>(2);
Assert.IsNotType<int>("hello");
Assert.IsNotType<long>("521");
Assert.IsNotType<double>(new object());
Assert.IsNotType<decimal>("55555");
Assert.IsNotType<DateTime>("2018-08-03");
Assert.IsNotType<AssertEqualDemo>(new object());
}
[Fact]
public void IsAssignableFrom_Test()
{
//可以从指定的类型派生
Assert.IsAssignableFrom<object>(22);
}
[Fact]
public void All_Test()
{
List<string> items = new List<string>() { "abc","ac","ad","adddeddd"};
Assert.All<string>(items, f => f.StartsWith("a"));
}
#region 清理
public void Dispose()
{
}
#endregion
}
}