代码之家  ›  专栏  ›  技术社区  ›  Sailing Judo

如何在嵌套中测试异常?

  •  2
  • Sailing Judo  · 技术社区  · 6 年前

    IGetResponse.OriginalException 财产。

    我首先设置了响应:

    var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
    A.CallTo(() => response.OriginalException).Returns(new Exception("Status code 404"));
    

    然后假弹性客户端:

    var client = A.Fake<Nest.IElasticClient>();
    A.CallTo(client)
        .WithReturnType<Nest.IGetResponse<Dictionary<string, object>>>()
        .Returns(response);
    

    客户端被注入到我正在测试的类中。

    OriginalException getter没有任何价值。它不为null,但没有任何属性具有任何值。我正期待着 OriginalException.Message 等于 .

    我还尝试将response对象设置为:

    var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
    A.CallTo(() => response.OriginalException.Message).Returns("Status code 404");
    

    ... 结果同样糟糕。

    我如何设置 IGetResponse 所以我可以评估 原始异常消息 在被测试的班级里?

        [TestMethod]
        [ExpectedException(typeof(NotFoundException))]
        public void Get_ClientReturns404_ThrowsNotFoundException()
        {
            // setup
            var request = new DataGetRequest
            {
                CollectionName = string.Empty,
                DocumentType = string.Empty,
                DataAccessType = string.Empty
            };
    
            var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
            A.CallTo(() => response.OriginalException.Message).Returns("Status code 404");
    
            var client = A.Fake<Nest.IElasticClient>();
            A.CallTo(client)
                .WithReturnType<Nest.IGetResponse<Dictionary<string, object>>>()
                .Returns(response);
    
            var elasticSearch = new ElasticSearch(null, client);
    
            // test
            var result = elasticSearch.Get(request);
    
            // assert
            Assert.Fail("Should have hit an exception.");
        }
    }
    

    下面是正在测试的方法:

        public async Task<Dictionary<string, object>> Get(DataGetRequest getRequest)
        {
            GetRequest request = new GetRequest(getRequest.CollectionName, getRequest.DocumentType, getRequest.Id);
            var response = await Client.GetAsync<Dictionary<string, object>>(request);
    
            if (response.OriginalException != null)
            {
                var message = response.OriginalException.Message;
                if (message.Contains("Status code 404"))
                    throw new NotFoundException(String.Format("Not Found for id {0}", getRequest.Id));
                else
                    throw new Exception(message);
            }                
    
            return response.Source;
        }
    

    IF块中的错误处理不是很健壮。一旦单元测试工作,那么代码将可能得到更多的爱。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Nkosi    6 年前

    模拟客户端的返回类型错误,因为 IElasticClient.GetAsync<> Task<IGetResponse<T>> .

    Task<IGetResponse<T>> GetAsync<T>(IGetRequest request, CancellationToken cancellationToken = default(CancellationToken)) where T : class;
    

    Source

    Task 允许异步代码的派生结果

    var response = await Client.GetAsync<Dictionary<string, object>>(request);
    

    按预期流动。

    例如

    [TestMethod]
    [ExpectedException(typeof(NotFoundException))]
    public async Task Get_ClientReturns404_ThrowsNotFoundException() {
    
        //Arrange
        var originalException = new Exception("Status code 404");
    
        var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
        A.CallTo(() => response.OriginalException).Returns(originalException);
    
        var client = A.Fake<Nest.IElasticClient>();
        A.CallTo(() => 
            client.GetAsync<Dictionary<string, object>>(A<IGetRequest>._, A<CancellationToken>._)
        ).Returns(Task.FromResult(response));
    
        var request = new DataGetRequest {
            CollectionName = string.Empty,
            DocumentType = string.Empty,
            DataAccessType = string.Empty
        };
    
        var elasticSearch = new ElasticSearch(null, client);
    
        // Act
        var result = await elasticSearch.Get(request);
    
        // Assert
        Assert.Fail("Should have hit an exception.");
    }