Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于状态的单元测试_C#_Unit Testing_Moq_Xunit - Fatal编程技术网

C# 基于状态的单元测试

C# 基于状态的单元测试,c#,unit-testing,moq,xunit,C#,Unit Testing,Moq,Xunit,假设我有一个名为CreateApplication的方法和一个私有助手方法GenerateApplication,该方法生成带有计算字段的应用程序对象。之后,我将生成的应用程序对象插入数据库 公共异步任务CreateApplication(CreateApplicationRequest) { var应用程序=生成应用程序(请求); 等待UnitOfWork.Application.InsertAsync(应用程序);//它与_db.Application.InsertAsync(应用程序)相同

假设我有一个名为
CreateApplication
的方法和一个私有助手方法
GenerateApplication
,该方法生成带有计算字段的应用程序对象。之后,我将生成的应用程序对象插入数据库

公共异步任务CreateApplication(CreateApplicationRequest)
{
var应用程序=生成应用程序(请求);
等待UnitOfWork.Application.InsertAsync(应用程序);//它与_db.Application.InsertAsync(应用程序)相同
wait UnitOfWork.CommitAsync();//它与_db.savechangessync()相同;
返回应用程序.Id;
}
对于这种情况,什么是合适的单元测试?我是否应该验证
InsertAsync
方法(将应用程序插入数据库),并检查应用程序对象是否正确生成

大概是这样的:

[事实]
公共异步任务CreateApplication\u何时调用\u应存储应用程序()
{
//我已经在构造函数中模拟了unitofwork
//当调用InsertAsync方法时,它会将传递的参数分配给声明的私有字段(应用程序)
应用程序;
UnitOfWork.Setup(x=>x.Application.InsertAsync(It.IsAny())
.回调(app=>application=app);
//表演
wait _applicationService.CreateApplication(新的createApplicationRequest());//伪请求
//断言
验证(x=>x.Application.InsertAsync(It.IsAny()),Times.Once);
验证(x=>x.CommitAsync(),Times.Once);
//这里我检查生成的应用程序的状态
Assert.Equal(application.CustomerId、request.CustomerId);
Assert.Equal(application.applicator.PhoneNumber,request.PhoneNumber);
Assert.Equal(application.LoanCurrencyId,request.LoanCurrencyId);
Assert.Equal(application.TermType、request.TermType);
断言.Equal(application.Term、request.Term);
断言相等(“01017054322_CC-01001”,申请文件编号);
Assert.Equal(application.GracePeriod、request.DefaultGracePeriod);
}

或者这不是一种正确的方法,最好在这种情况下使用集成测试?

有几种方法可以对方法进行单元测试。最流行的两种测试是黑盒测试和白盒测试

黑盒测试 你对实现一无所知。您只关心输出(包括返回值、输出参数和副作用)。因此,您希望确保无论何时使用给定的输入调用它,都能看到预期的输出

在这种情况下,测试将只检查返回的Guid,并验证应用程序是否存储在模拟存储中

Assert.NotEqual(结果,Guid.Empty);
Assert.NotNull(x.Application.FirstOrDefault(app=>app.Id==result));
这种方法可以很容易地扩展到集成测试,而不是使用模拟存储,您可以使用存储的沙箱版本

白盒测试 您知道您的方法是如何实现的。您希望确保代码不会执行任何不必要的操作,例如在
GenerateApplication
InsertAsync
方法调用之间重写应用程序的某些属性

这可能是好的,也可能是坏的,这取决于你如何看待它。假设您需要规范化
PhoneNumber
,并且出于任何原因在
CreateApplication
中执行此操作。从黑盒的角度来看,这并不重要(不需要更新测试),因为功能没有改变。从白盒的角度来看,您需要调整测试以模拟规范化器,验证其调用并断言预期的输出


从回归的角度来看,前者可以被视为一个安全网,而后者可以被视为重构的安全网。

您的单元测试还可以,这里的关键是这不是单元测试或集成测试,为什么两者都不能?我想了很多,决定只使用集成测试。如果应用程序生成正确,我将检查数据库的结果