C# 如何在Moq设置方法中返回DbRawSqlQuery
我有一个过程服务,它只包含如下方法:C# 如何在Moq设置方法中返回DbRawSqlQuery,c#,unit-testing,moq,C#,Unit Testing,Moq,我有一个过程服务,它只包含如下方法: DbRawSqlQuery<UserVesselPermissionsResult> GetUserVesselPermissions(Guid userId, DateTime date); 目前,由于无法轻松实例化的原因,DbRawSqlQuery,它无法工作 编辑1: 以下是一些更详细的信息: public class IMembershipService { private readonly IProcedureService
DbRawSqlQuery<UserVesselPermissionsResult> GetUserVesselPermissions(Guid userId, DateTime date);
目前,由于无法轻松实例化的原因,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
}
}
公共类IMembershipService
{
私有只读IProceduceReserve(程序保留);
公共会员服务(IProcedureService procedureService)
{
_程序保留=程序保留;
}
public List UserPermissions=>\u procedureService.GetUserVesselPermissions(UserId,DateTime.Now).ToList();
public bool UserHasPermissionOrAdmin(YcoEnum.UIPermission)
{
如果(iUserAdministrator)
返回true;
var uservesselpowpermissions=uservesselpowpermissions;//我必须在这里进行设置
如果(userVesselPermissions==null)
返回false;
var userSelectedVesselId=userSelectedVesselId;
归还某物
}
}
试验方法如下所示:
[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));
}
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();
}
}
_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
new UserVesselPermissionsResult
{
PermissionId = 1
}
}));
[TestCase(true)]
[测试用例(错误)]
public void UserHasAllPermissionsOrAdmin\u isAdmin\u ReturnsTrue(bool isAdmin)
{
//安排
_membershipService.IsUserAdministrator=isAdmin;
var索赔=新列表()
{
新索赔(ClaimTypes.Name,“rajmondi@outlook.com"),
新声明(ClaimTypes.NameIdentifier,Guid.NewGuid().ToString())
};
var标识=新的索赔实体(索赔,“TestAuthType”);
var claimsPrincipal=新的claimsPrincipal(标识);
_authenticationManager.Setup(x=>x.User).Returns(claimsPrincipal);
_procedureService.Setup(x=>x.GetUserVesselPermissions(It.IsAny(),It.IsAny())
.Returns((DbRawSqlQuery)null);//由于DbRawSqlQuery,我不知道如何设置它
//行动
var result=\u membershipService.UserHasAllPermissions(It.IsAny());
//断言
Assert.That(result,Is.EqualTo(true));
}
非常感谢您的帮助
干杯 我可以让它工作,实际上我不喜欢改变整个
IProcedureService
的想法,因为它确实从实体框架返回了一个内置的int类型。由于我从过程服务获取数据并将其返回到IEnumerable
中,所以我只需要关心GetEnumerator()
方法,所以我想首先检查代码是如何构造的,我发现DbSqlQuery
是从DbRawSqlQuery
继承的,没有内部构造函数的问题。在本例中,我创建了一个名为TestDbSqlQuery
的新类,该类将从DbSqlQuery
继承。这个类看起来像这样:
[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));
}
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();
}
}
_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
new UserVesselPermissionsResult
{
PermissionId = 1
}
}));
公共类TestDbSqlQuery:DbSqlQuery其中T:class
{
私有只读列表_innerList;
公共TestDbSqlQuery(列表innerList)
{
_innerList=innerList;
}
公共重写IEnumerator GetEnumerator()
{
返回_innerList.GetEnumerator();
}
}
我特意添加了Lis
作为参数,这样我就可以将数据存储在该列表中,然后使用覆盖的IEnumerator
因此,现在的测试方法如下:
[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));
}
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();
}
}
_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
new UserVesselPermissionsResult
{
PermissionId = 1
}
}));
\u procedureService.Setup(x=>x.GetUserVesselPermissions(It.IsAny(),It.IsAny())
.Returns(新TestDbSqlQuery(新列表
{
新用户VesselPermissionsResult
{
PermissionId=1
}
}));
它工作正常,最后可以根据需要修改
TestDbSqlQuery
,但想法是一样的,只需将对象存储在某个容器中,然后在GetEnumerator
方法中检索它们。我可以让它工作,实际上,我不喜欢改变整个IProcedureService
的想法,因为它确实从实体框架返回了一个构建的int类型。由于我从过程服务获取数据并将其返回到IEnumerable
中,所以我只需要关心GetEnumerator()
方法,所以我想首先检查代码是如何构造的,我发现DbSqlQuery
是从DbRawSqlQuery
继承的,没有内部构造函数的问题。在本例中,我创建了一个名为TestDbSqlQuery
的新类,该类将从DbSqlQuery
继承。这个类看起来像这样:
[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));
}
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();
}
}
_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
new UserVesselPermissionsResult
{
PermissionId = 1
}
}));
公共类TestDbSqlQuery:DbSqlQuery其中T:class
{
私有只读列表_innerList;
公共TestDbSqlQuery(列表innerList)
{
_innerList=innerList;
}
公共重写IEnumerator GetEnumerator()
{
返回_innerList.GetEnumerator();
}
}
我特意添加了Lis
作为参数,这样我就可以将数据存储在该列表中,然后使用覆盖的IEnumerator
因此,现在的测试方法如下:
[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));
}
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();
}
}
_procedureService.Setup(x => x.GetUserVesselPermissions(It.IsAny<Guid>(), It.IsAny<DateTime>()))
.Returns(new TestDbSqlQuery<UserVesselPermissionsResult>(new List<UserVesselPermissionsResult>
{
new UserVesselPermissionsResult
{
PermissionId = 1
}
}));
\u procedureService.Setup(x=>x.GetUserVesselPermissions(It.IsAny(),It.IsAny())
.Returns(新TestDbSqlQuery(新列表
{
新用户VesselPermissionsResult
{
PermissionId=1
}
}));
它工作正常,最后可以根据需要修改
TestDbSqlQuery
,但想法是一样的,只需将对象存储在某个容器中,然后在GetEnumerator
方法中检索它们。您的代码与第三方API紧密耦合,这使得很难模拟您不拥有的对象。长话短说,Moq不能做你想做的事。考虑一下当前的设计选择。@ NKOSI编辑了这个问题,这样你就可以给我一个想法,我在服务本身有一个设计问题,谢谢:你把你的代码紧密耦合到第三方API,这使得很难模拟你不拥有的东西。长话短说,Moq不能做你想做的事。考虑一下当前的设计选择。@ NKOSI编辑了这个问题,这样你可以给我一个想法,我在服务本身有一个设计问题,谢谢: