如何在 Nest 中测试异常?
How to test for exception in Nest?
当 Nest 在 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);
客户端被注入到我正在测试的 class。
然而,当单步执行代码时,当客户端调用它时 returns 一个伪造的响应,但是 OriginalException
getter 没有任何价值。它不为空,但 none 的属性具有任何值。我期望 OriginalException.Message
等于 状态代码 404。
我还尝试将响应对象设置为:
var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
A.CallTo(() => response.OriginalException.Message).Returns("Status code 404");
...结果同样糟糕。
如何设置 IGetResponse
以便我可以在正在测试的 class 中评估 OriginalException.Message
?
请求了更多代码。我可以展示整个测试,我会展示被测试的方法。这是我的整个测试:
[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 块中的错误处理不是很可靠。一旦单元测试有效,那么代码可能会受到更多的喜爱。
模拟客户端的 return 类型是错误的,因为 IElasticClient.GetAsync<>
return 是 Task<IGetResponse<T>>
.
Task<IGetResponse<T>> GetAsync<T>(IGetRequest request, CancellationToken cancellationToken = default(CancellationToken)) where T : class;
所以设置需要return一个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.");
}
当 Nest 在 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);
客户端被注入到我正在测试的 class。
然而,当单步执行代码时,当客户端调用它时 returns 一个伪造的响应,但是 OriginalException
getter 没有任何价值。它不为空,但 none 的属性具有任何值。我期望 OriginalException.Message
等于 状态代码 404。
我还尝试将响应对象设置为:
var response = A.Fake<Nest.IGetResponse<Dictionary<string, object>>>();
A.CallTo(() => response.OriginalException.Message).Returns("Status code 404");
...结果同样糟糕。
如何设置 IGetResponse
以便我可以在正在测试的 class 中评估 OriginalException.Message
?
请求了更多代码。我可以展示整个测试,我会展示被测试的方法。这是我的整个测试:
[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 块中的错误处理不是很可靠。一旦单元测试有效,那么代码可能会受到更多的喜爱。
模拟客户端的 return 类型是错误的,因为 IElasticClient.GetAsync<>
return 是 Task<IGetResponse<T>>
.
Task<IGetResponse<T>> GetAsync<T>(IGetRequest request, CancellationToken cancellationToken = default(CancellationToken)) where T : class;
所以设置需要return一个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.");
}