以下是我的通用基础存储库接口
public interface IRepository<T>
{
IQueryable<T> AllIncluding(params Expression<Func<T,
object>>[] includeProperties);
}
我的实体
public class Sdk
{
public Sdk()
{
this.Identifier = Guid.NewGuid().ToString();
}
public virtual ICollection<Resource> AccessibleResources { get; set; }
public string Identifier { get; set; }
}
以下是具体的回购
public interface ISdkRepository : IRepository<Sdk>
{
}
现在我正在尝试使用moq
测试控制器以下是我要测试的代码
public ActionResult GetResources(string clientId) {
var sdkObject = sdkRepository
.AllIncluding(k => k.AccessibleResources)
.SingleOrDefault(k => k.Identifier == clientId);
if (sdkObject == null)
throw new ApplicationException("Sdk Not Found");
return Json(sdkObject.AccessibleResources.ToList());
}
使用以下测试
[Test]
public void Can_Get_GetResources()
{
var cid = Guid.NewGuid().ToString();
var mockRepo = new Moq.Mock<ISdkRepository>();
var sdks = new HashSet<Sdk>()
{
new Sdk()
{
Identifier = cid,
AccessibleResources = new HashSet<Resource>()
{
new Resource()
{
Id = Guid.NewGuid(),
Description = "This is sdk"
}
}
}
};
mockRepo.Setup(k => k.
AllIncluding(It.IsAny<Expression<Func<Sdk,object>>[]>()))
.Returns(sdks.AsQueryable);
var sdkCtrl = new SdksController(mockRepo.Object);
var returnedJson=sdkCtrl.GetResources(cid);
returnedJson.ToString();
}
它正在抛出:
System.Reflection.TargetParameterCountException:参数计数不匹配
不知道为什么?
答案 0 :(得分:29)
虽然有一个标记为已接受的答案,但我相信有一种方法可以正确地模拟您的存储库。
而不是
mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>()))
.Returns(sdks.AsQueryable);
请使用
mockRepo.Setup(k => k.AllIncluding(It.IsAny<Expression<Func<Sdk, object>>[]>()))
.Returns((Expression<Func<Sdk,
object>>[] includeProperties) => sdks.AsQueryable());
答案 1 :(得分:7)
解决此问题的另一个解决方案是使用:.AsQueryable()
代替.AsQueryable
。
答案 2 :(得分:5)
我认为你在Moq遇到了一些限制。它不能很好地处理表达式参数,因为它可以将表达式作为值本身传递。 Moq无法知道表达式的哪个部分有待解决,以及签名的一部分。
另外,我不记得Moq如何处理params xx [],但你很可能在这里遇到两个问题的组合。
您是否可以创建一个将表达式公开为属性的类?如果是这样,可以更改AllIncluding的签名并告诉Moq匹配该类的任何实例。
<强>更新强>
在回答时,这是一个限制,但现在可以。请参阅Oleksandr Lytvyn的答案
答案 3 :(得分:1)
对于寻找答案的其他人,我的解决方案是在Setup
中添加与Returns
中的表达式相同数量的参数。
例如:
不使用不同的参数计数
mock.Setup(x => x.DoSomething(It.IsAny<string>(), It.IsAny<string>()))
.Returns((string s) => s.ToLower());
在Returns
中使用与Setup
mock.Setup(x => x.DoSomething(It.IsAny<string>()))
.Returns((string s1, string s2) => s1.ToLower());