在程序开发中测试和单元测试是两种不同的操作,测试一般是指定程序中在程序部署试运营前查看工程的各种功能是否运行流畅,测试过程中会有一些Bug会被呈现并解决,即测试是整体性的联动机制性的功能验证。单元测试则工程性程序必须不可少的组成部分,它使用的最小细粒度为对指定的方法的功能实现进行验证,它一般会能使边界数据来测试指定方法在功能的实现上是否会出现Bug,如果出现Bug测就需要对该方法进行重构了,即单元测试是局部性甚至是零部件性的功能验证
nopCommerce程序单元测试定义实现是在Nunit框架的基础上进行定义实现的,断言操作是通过第3方法中间件FluentAssertions成员方法,而非Nunit框架的内置的断言成员方法。
1 单元测试的基本实现
1 BaseNopTest
namespace Nop.Tests
{
public partial class BaseNopTest
{
private static readonly ServiceProvider _serviceProvider;
protected BaseNopTest()
{
}
static BaseNopTest()
{
//获取.NetCore框架内置依赖注入容器实例。
var services = new ServiceCollection();
//把地址服务接口及其地址服务注入到.NetCore框架内置依赖注入容器实例中。
services.AddTransient
//获取.NetCore框架内置依赖注入容器的提供程序实例,以使可以通过提供程序实例,来获取已经注入到.NetCore框架内置依赖注入容器中指定接口或具体实现类的实例。
_serviceProvider = services.BuildServiceProvider();
}
///
///
/// 【获取服务】
///
/// 摘要:
/// .NetCore框架内置依赖注入容器的提供程序实例,来获取已经注入到.NetCore框架内置依赖注入容器中1个指定接口或具体实现类的实例。
///
///
/// 1个指定接口或具体实现类的实例。
///
public static T GetService<T>()
{
try
{
return _serviceProvider.GetRequiredService
}
catch (InvalidOperationException)
{
return (T)EngineContext.Current.ResolveUnregistered(typeof(T));
}
}
}
}
2 AddressTests
using FluentAssertions;
using Nop.Core.Domain.Common;
using Nop.Services.Common;
using NUnit.Framework;
namespace Nop.Tests.Domain.Common
{
// [TestFixture]标记:当前类被标记为在“NUnit”框架基础上进行定义单元测试类
[TestFixture]
public class AddressTests : BaseNopTest
{
///
/// 【地址复制】
///
/// 摘要:
/// 用于验证地址实体1个原指定实例的属性成员实例,与复制指定实例的对应属性成员实例之间是否相等。
///
[Test]
public void CanCloneAddress()
{
var address = new Address
{
Id = 1,
FirstName = "FirstName 1",
LastName = "LastName 1",
Email = "Email 1",
Company = "Company 1",
CountryId = 3,
StateProvinceId = 4,
City = "City 1",
County = "County 1",
Address1 = "Address1",
Address2 = "Address2",
ZipPostalCode = "ZipPostalCode 1",
PhoneNumber = "PhoneNumber 1",
FaxNumber = "FaxNumber 1",
CreatedOnUtc = new DateTime(2010, 01, 01),
};
var addressService = GetService
var newAddress = addressService.CloneAddress(address);
//通过FluentAssertions中间件方法,对地址实体1个指定实例的属性成员实例进行单元测试的断言。
newAddress.Should().NotBeNull();
newAddress.Id.Should().Be(0);
newAddress.FirstName.Should().Be("FirstName 1");
newAddress.LastName.Should().Be("LastName 1");
newAddress.Email.Should().Be("Email 1");
newAddress.Company.Should().Be("Company 1");
newAddress.City.Should().Be("City 1");
newAddress.County.Should().Be("County 1");
newAddress.Address1.Should().Be("Address1");
newAddress.Address2.Should().Be("Address2");
newAddress.ZipPostalCode.Should().Be("ZipPostalCode 1");
newAddress.PhoneNumber.Should().Be("PhoneNumber 1");
newAddress.FaxNumber.Should().Be("FaxNumber 1");
//以下这些数据验证操作是属于表单验证中间件DataAnnotations或FluentValidation进行验证操作的实现范畴,需要非定义的单元测试的断言操作中。
newAddress.CreatedOnUtc.Should().Be(new DateTime(2010, 01, 01));
newAddress.CountryId.Should().Be(3);
newAddress.StateProvinceId.Should().Be(4);
}
}
}
注意:单元测试的目的是通过边界数据,来断言指定方法是否存在Bug,但CanCloneAddress方法只是一个常规性的功能方法,在具体实现中该方法只要能够正常运行就不可能出现Bug,所以nopCommerce开发者以对CanCloneAddress方法进行单元测试显得十分不必要。
对以上功能更为具体实现和注释见:22-09-11-070_Nop_4.40.4(单元测试)。