如何在Moq设置方法中返回DbRawSqlQuery

时间:2018-08-30 23:35:23

标签: c# unit-testing moq

我有一个过程服务,其中仅包含这样的方法:

DbRawSqlQuery<UserVesselPermissionsResult> GetUserVesselPermissions(Guid userId, DateTime date);

因此,所有方法都返回DbRawSqlQuery,然后在应用程序的上层,将它们转换为IEnumerable。但出于某些地方的测试目的,我必须设置此方法。问题是类DbRawSqlQuery确实有一个内部构造函数(我知道Moq不接受内部构造函数),但我不知道是否有某种方法可以使此代码起作用:

_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
            .Returns(new DbRawSqlQuery<UserVesselPermissionsResult>(null));

当前由于DbRawSqlQuery不能轻易实例化而无法正常工作。

编辑1:

以下是更多详细信息:

public class IMembershipService
{
    private readonly IProcedureService _procedureService;
    public MembershipService(IProcedureService procedureService)
    {
        _procedureService = procedureService;
    }

    public List<UserVesselPermissionsResult> UserPermissions => _procedureService.GetUserVesselPermissions(UserId, DateTime.Now).ToList();


    public bool UserHasPermissionOrAdmin(YcoEnum.UIPermission permission)
    {
        if (IsUserAdministrator)
            return true;
        var userVesselPermissions = UserVesselPermissions; //Here I have to make the setup
        if (userVesselPermissions == null)
            return false;
        var userSelectedVesselId = UserSelectedVesselId;
        return //something
    } 
}

测试方法如下:

[TestCase(true)]
[TestCase(false)]
public void UserHasAllPermissionsOrAdmin_IsAdminOrNot_ReturnsTrue(bool isAdmin)
{ 
    //Arrange
    _membershipService.IsUserAdministrator = isAdmin;
    var claims = new List<Claim>()
    {
        new Claim(ClaimTypes.Name, "rajmondi@outlook.com"),
        new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString())
    };
    var identity = new ClaimsIdentity(claims, "TestAuthType");
    var claimsPrincipal = new ClaimsPrincipal(identity);
    _authenticationManager.Setup(x => x.User).Returns(claimsPrincipal);

    _procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
        .Returns((DbRawSqlQuery<UserVesselPermissionsResult>) null);//Here I dont know how to set it up due to DbRawSqlQuery
    //Action

    var result = _membershipService.UserHasAllPermissions(It.IsAny<YcoEnum.UIPermission>());
    //Assert
    Assert.That(result, Is.EqualTo(true));
}

非常感谢您的帮助!

干杯!

1 个答案:

答案 0 :(得分:1)

我可以使它工作,实际上我不喜欢更改整个IProcedureService的想法,因为它确实从实体框架返回了一个内置的类型。由于我是从过程服务中获取数据并将其返回到IEnumerable的,所以我只需要关心GetEnumerator()方法,因此我想到的是首先检查内部代码的构造方式,我发现DbSqlQuery是从DbRawSqlQuery继承的,没有内部构造函数的问题。在这种情况下,我创建了一个名为TestDbSqlQuery的新类,该类将从DbSqlQuery继承。该类如下所示:

public class TestDbSqlQuery<T> : DbSqlQuery<T> where T : class
{
    private readonly List<T> _innerList; 

    public TestDbSqlQuery(List<T> innerList)
    {
        _innerList = innerList;
    }

    public override IEnumerator<T> GetEnumerator()
    {
        return _innerList.GetEnumerator();
    }
}

我特意添加了Lis<T>作为参数,以便可以将数据存储在该列表中,然后使用覆盖的IEnumerator<T>

因此,现在的测试方法如下:

_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
    new UserVesselPermissionsResult
    {
        PermissionId = 1
    }
}));

并且运行良好,最后TestDbSqlQuery可以根据需要进行修改,但是想法是相同的,只是将对象存储在某个容器中,然后使用GetEnumerator方法进行检索。 / p>