c# - 如何将参数传递给使用 System.Action 作为输入参数的数据访问层?

标签 c# unit-testing nsubstitute

我正在尝试为我最近继承的应用程序创建一些单元测试。目前正在使用 NSubstitute,因为这是以前的程序员使用的,但我不喜欢它。

我正在测试的方法调用 DataService 类的 Create 方法。

调用创建方法

var contactProductLink = this.dsService.Create<ContactProductLink>(x =>
{
    x.ContactRoleId = prod.RoleId;
    x.ContactId = contactViewModel.ContactId;
    x.ProductId = prod.ProductId;
    x.Active = true;
    x.InsertDate = DateTime.Now;
    x.InsertUserId = user.employeeId;
    x.UpdateDate = DateTime.Now;
    x.UpdateUserId = user.employeeId;
});

数据服务创建方法:

public TEntity Create<TEntity>(Action<TEntity> propertySetter = null) where TEntity : class
{
    var tEntity = this.Context.Create<TEntity>();
    if (propertySetter != null)
    {
        propertySetter(tEntity);
    }

    return tEntity;
}

我采用的方法(也许还有更好的方法)是使用 NSubstitute 来模拟数据服务。当我最后做断言时,我会检查以确保调用了 Create 方法:

mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());

但是,我还想验证发送到该方法的输入是否正确,这就是我遇到麻烦的地方。我可以获得传递给 Create 方法的 System.Action 对象,但我不知道如何提取参数(例如调用创建方法代码片段中发布的 ContactRoleId、ContactId 等)。

所以在所有这些之后我要问的是:

  1. 如何访问这些输入参数,以便我可以验证是否将正确的参数传递给了数据服务?有可能吗?
  2. 有没有比我目前正在尝试做的更好的方法来做到这一点?

解决方案

//Arrange
mockDataSupplierService.Create<ContactProductLink>(Arg.Do<Action<ContactProductLink>>(x=> actionToPopulateEntity = x));

//Assert
mockDataSupplierService.Received().Create<ContactProductLink>(Arg.Any<Action<ContactProductLink>>());
var entity = new ContactProductLink();
actionToPopulateEntity.Invoke(entity);
Assert.AreEqual(ExpectedContactId, entity.ContactId);

最佳答案

How can I access those input parameters so I can verify the correct arguments are being passed to the data service? Is it even possible?

基本上你不能,因为不可能从 Action 中提取“代码”细节(考虑当你传递一个没有设置任何属性的 Action 时会发生什么 - 这是完全合法的,但会破坏假设的机制) .

但是,您可以尝试这样做:

  1. 创建具有初始值的实体
  2. 使用Arg.Invoke参数,告诉 NSubstitute 使用选定的对象作为 Action 参数
  3. 验证实体属性值是否已更改

例如:

// Arrange
var entity = new ContactProductLink
{
    ContactRoleId = // ...
    // ...
};

mockDataSupplierService
    .Create<ContactProductLink>(Arg<ContactProductLink>.Invoke(entity));

// Act
// ...

Assert.That(entity.ContactRoleId, Is.EqualTo(2));
// ...

关于c# - 如何将参数传递给使用 System.Action 作为输入参数的数据访问层?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14128927/

相关文章:

c# - 从桌面应用程序运行 Windows 10 的相机应用程序

javascript - React 测试 componentWillReceiveProps

javascript - 如何使用 practicalmeteor :mocha 对 meteor 方法进行单元测试

python - 使用unittest.mock.patch时,为什么autospec默认不是True?

c# - 覆盖 Autofixture 自定义设置

c# - WPF 功能区 : Maximized window going off screen

c# - Azure Batch - 资源文件准备任务

c# - 用 NSubstitute 模拟泛型方法

unit-testing - NSubstitute:无法模拟与没有相应 setter 的成员变量关联的语法糖 getter 方法

c# - 异步设置 Thread.CurrentPrincipal?