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

时间:2013-01-02 20:48:40

标签: 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;
});

DataService创建方法:

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来模拟DataService。当我在最后执行断言时,我正在检查以确保调用Create方法:

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

但是,我还要验证发送到方法的输入是否正确,这是我遇到麻烦的地方。我可以获取传递给Create方法的System.Action对象,但我无法弄清楚如何提取参数(例如调用create方法代码片段中发布的ContactRoleId,ContactId等)。 / p>

所以我要问的是:

  1. 如何访问这些输入参数,以便验证是否将正确的参数传递给数据服务?它甚至可能吗?
  2. 有没有比我目前要做的更好的方法呢?
  3. 解决方案

    //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);
    

1 个答案:

答案 0 :(得分:3)

  

如何访问这些输入参数,以便验证是否将正确的参数传递给数据服务?它甚至可能吗?

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

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

  1. 创建具有初始值的实体
  2. 使用Arg.Invoke参数,告诉 NSubstitute将所选对象用作操作参数
  3. 验证实体属性值是否已更改
  4. 例如:

    // Arrange
    var entity = new ContactProductLink
    {
        ContactRoleId = // ...
        // ...
    };
    
    mockDataSupplierService
        .Create<ContactProductLink>(Arg<ContactProductLink>.Invoke(entity));
    
    // Act
    // ...
    
    Assert.That(entity.ContactRoleId, Is.EqualTo(2));
    // ...