C# 无法为接口模拟传递构造函数参数(模拟IFeedResponse)

C# 无法为接口模拟传递构造函数参数(模拟IFeedResponse),c#,azure,unit-testing,moq,azure-cosmosdb,C#,Azure,Unit Testing,Moq,Azure Cosmosdb,我正在尝试为DocumentDBRepository分页代码编写单元测试。由于FeedResponse中涉及到延续令牌,因此我需要模拟FeedResponse,以便为FeedResponse.ContinuationToken输入一些值。但问题是我犯了一个错误说: 消息:System.ArgumentException:构造函数参数不能为空 为接口模拟传递 这是否意味着我无法模拟FeedResponse?或者我使用FeedResponse的方式是错误的 这是我的密码: var response

我正在尝试为
DocumentDBRepository
分页代码编写单元测试。由于
FeedResponse
中涉及到延续令牌,因此我需要模拟
FeedResponse
,以便为
FeedResponse.ContinuationToken
输入一些值。但问题是我犯了一个错误说:

消息:System.ArgumentException:构造函数参数不能为空 为接口模拟传递

这是否意味着我无法模拟
FeedResponse
?或者我使用FeedResponse的方式是错误的

这是我的密码:

var response = new Mock<IFeedResponse<T>>(expected);
response.Setup(_ => _.ResponseContinuation).Returns(It.IsAny<string>());
var mockDocumentQuery = new Mock<IFakeDocumentQuery<T>>();

mockDocumentQuery
    .SetupSequence(_ => _.HasMoreResults)
    .Returns(true)
    .Returns(false);

mockDocumentQuery
    .Setup(_ => _.ExecuteNextAsync<T>(It.IsAny<CancellationToken>()))
    .Returns((Task<FeedResponse<T>>)response.Object);
var响应=新模拟(预期);
response.Setup(=>u.ResponseContinuation).Returns(It.IsAny());
var mockDocumentQuery=new Mock();
模拟文档查询
.SetupSequence(=>0.HasMoreResults)
.Returns(true)
。报税表(虚假);
模拟文档查询
.Setup(=>u.ExecuteNextAsync(It.IsAny()))
.Returns((任务)response.Object);

当我调试时,断点在
var response=newmock(预期)处停止然后发生了错误

错误是因为您在模拟接口并试图传递构造函数参数。这将无法按照错误消息所述工作

但是,您可以使用
FeedResponse
的实际实例

给定的成员不是<代码>虚拟< /代码>,也是只读的,您可以考虑中断类并重写默认行为,因为<代码> FoeRebug < /代码>不是<代码>密封< /代码> .< 比如说

public class FeedResponseStub<T> : FeedResponse<T> {
    private string token;

    public FeedResponseStub(IEnumerable<T> result, string token)
        : base(result) {
        this.token = token;
    }

    public new string ResponseContinuation {
        get {
            return token;
        }
    }
}
公共类FeedResponseSub:FeedResponse{
私有字符串令牌;
公共FeedResponseSub(IEnumerable结果,字符串标记)
:基准(结果){
this.token=token;
}
公共新字符串响应继续{
得到{
返回令牌;
}
}
}
并在测试中使用存根

//...

var token = ".....";
var response = new FeedResponseStub<T>(expected, token);

//...

mockDocumentQuery
    .Setup(_ => _.ExecuteNextAsync<T>(It.IsAny<CancellationToken>()))
    .ReturnsAsync(response);

//...
/。。。
var token=“…”;
var响应=新的FeedResponseSub(预期,令牌);
//...
模拟文档查询
.Setup(=>u.ExecuteNextAsync(It.IsAny()))
.ReturnsAsync(答复);
//...

错误是因为您在模拟接口并试图传递构造函数参数。这将无法按照错误消息所述工作

但是,您可以使用
FeedResponse
的实际实例

给定的成员不是<代码>虚拟< /代码>,也是只读的,您可以考虑中断类并重写默认行为,因为<代码> FoeRebug < /代码>不是<代码>密封< /代码> .< 比如说

public class FeedResponseStub<T> : FeedResponse<T> {
    private string token;

    public FeedResponseStub(IEnumerable<T> result, string token)
        : base(result) {
        this.token = token;
    }

    public new string ResponseContinuation {
        get {
            return token;
        }
    }
}
公共类FeedResponseSub:FeedResponse{
私有字符串令牌;
公共FeedResponseSub(IEnumerable结果,字符串标记)
:基准(结果){
this.token=token;
}
公共新字符串响应继续{
得到{
返回令牌;
}
}
}
并在测试中使用存根

//...

var token = ".....";
var response = new FeedResponseStub<T>(expected, token);

//...

mockDocumentQuery
    .Setup(_ => _.ExecuteNextAsync<T>(It.IsAny<CancellationToken>()))
    .ReturnsAsync(response);

//...
/。。。
var token=“…”;
var响应=新的FeedResponseSub(预期,令牌);
//...
模拟文档查询
.Setup(=>u.ExecuteNextAsync(It.IsAny()))
.ReturnsAsync(答复);
//...

以下是我在这方面的工作方法

publicstaticfeedresponse-ToFeedResponse(此IQueryable资源,IDictionary responseHeaders=null)
{
var feedResponseType=Type.GetType(“Microsoft.Azure.Documents.Client.FeedResponse`1,Microsoft.Azure.DocumentDB.Core,Version=1.9.1.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”);
var flags=BindingFlags.NonPublic | BindingFlags.Instance;
var headers=newnamevalueCollection
{
{“x-ms-request-charge”,“0”},
{“x-ms-activity-id”,Guid.NewGuid().ToString()}
};
if(响应负责人!=null)
{
foreach(var responseHeader中的var responseHeader)
{
headers[responseHeader.Key]=responseHeader.Value;
}
}
var arguments=new object[]{resource,resource.Count(),headers,false,null};
if(feedResponseType!=null)
{
var t=feedResponseType.MakeGenericType(typeof(t));
var feedResponse=Activator.CreateInstance(t,标志,null,参数,null);
返回(FeedResponse)FeedResponse;
}
返回新的FeedResponse();
}
}
您可以在字典中将延续令牌作为头键值传递,以设置FeedResponse值。 您可以通过将
x-ms-continuation
值设置为令牌来实现这一点

请记住,
FeedResponse
ResponseContinuation
属性也考虑了
useETagAsContinuation
值。在反射调用的构造函数中,我将其默认为false


如需进一步参考,请查看项目代码和单元测试的编写方式。

以下是我在中解决此问题的方法

publicstaticfeedresponse-ToFeedResponse(此IQueryable资源,IDictionary responseHeaders=null)
{
var feedResponseType=Type.GetType(“Microsoft.Azure.Documents.Client.FeedResponse`1,Microsoft.Azure.DocumentDB.Core,Version=1.9.1.0,Culture=neutral,PublicKeyToken=31bf3856ad364e35”);
var flags=BindingFlags.NonPublic | BindingFlags.Instance;
var headers=newnamevalueCollection
{
{“x-ms-request-charge”,“0”},
{“x-ms-activity-id”,Guid.NewGuid().ToString()}
};
if(响应负责人!=null)
{
foreach(var responseHeader中的var responseHeader)
{
headers[responseHeader.Key]=responseHeader.Value;
}
}
var arguments=new object[]{resource,resource.Count(),headers,false,null};
if(feedResponseType!=null)
{
var t=feedResponseType.MakeGenericType(typeof(t));
var feedResponse=Activator.CreateInstance(t,标志