如何模拟Azure DocumentDB客户端库引发的DocumentClientException?

qua*_*cle 5 c# unit-testing azure-cosmosdb

我正在尝试围绕查询Azure Document DB的代码编写一些单元测试.特别是,我正在努力确保错误处理正常工作.唯一的困难是我无法模拟DocumentClientException客户端库在从DocumentDB收到错误时抛出的类.DocumentClientException实现ISerializable,所以当我尝试模拟它(使用Moq)时,我得到一个异常,说模拟对象未能提供反序列化构造函数.

有没有人成功模拟过Azure DocumentDB文档客户端异常?如果是这样,你是怎么做到的?或者我的测试策略是完全关闭的?

Raj*_*dar 21

您的单元测试代码不应连接到真正的Azure DocumentDb.

将Azure客户端类包装在一个接口中,并在具体类的方法中,进行DocumentDB调用.这是你的真实代码.

当你单元测试这个方法的调用者类时,模拟包装器接口,将它注入正在测试的类中,并在Moq设置中自己抛出一个DocumentClientException.并测试场景.

由于DocumentClientException只有内部构造函数,因此值得使用反射构造它的测试方法.(这肯定是一个打击,但作为测试代码,您可以选择可测试性与几毫秒)

    private static DocumentClientException CreateDocumentClientExceptionForTesting(
                                           Error error, HttpStatusCode httpStatusCode)
    {
        var type = typeof (DocumentClientException);

        // we are using the overload with 3 parameters (error, responseheaders, statuscode)
       // use any one appropriate for you.

        var documentClientExceptionInstance = type.Assembly.CreateInstance(type.FullName, 
            false, BindingFlags.Instance | BindingFlags.NonPublic, null,
            new object[] {error, (HttpResponseHeaders) null, httpStatusCode}, null, null);

        return (DocumentClientException)documentClientExceptionInstance;
    }
Run Code Online (Sandbox Code Playgroud)

然后让呼叫者使用它们,

        var error = new Error
        {
            Id = Guid.NewGuid().ToString(),
            Code = "some_code",
            Message = "some_message"
        };


        var testException = CreateDocumentClientExceptionForTesting(error, 
                                           HttpStatusCode.InternalServerError);

        // make Moq throw testException
Run Code Online (Sandbox Code Playgroud)

  • 哦是的..我忘了那个家伙只有内部构造函数..用我通常在测试项目中使用的辅助方法修改答案 (3认同)
  • 这太棒了! (3认同)