在 NEST 中使用 InMemoryConnection 多次调用 Elasticsearch
Using InMemoryConnection in NEST with multiple calls to Elasticsearch
我正在从对 Elasticsearch 的模拟调用(通过 NEST)转向使用 InMemoryConnection
class 和一些硬编码的 JSON 来模拟真实的 Elasticsearch 响应来自C# 代码。效果很好,比 mock 好得多,mock 需要对 NEST 的实现方式有深刻的理解和知识,而且很容易出错。
我的问题是,如果我想模拟对 Elasticsearch 的多次调用,我看不到任何简单的方法。 InMemoryConnection
仅接受单个 JSON 字符串:
var connection = new InMemoryConnection(Encoding.UTF8.GetBytes(json));
最好是这样说,return 第一次通话时为 x,第二次通话时为 y。
类似的问题出现在验证对 Elasticsearch 的调用时。我可以使用 OnRequestCompleted
设置几个布尔值,如下所示:
OnRequestCompleted(response =>
{
if (response.Uri.ToString().Contains("/blabla/_search")) {}
else if (response.HttpMethod == HttpMethod.POST && response.Success && response.Uri.ToString().StartsWith("http://localhost:9200/blabla"))
wasCalled = true;
else // We don't expect any other calls
failed = true;
})
对这些布尔值进行断言时。但这感觉不对。
如有任何想法,我们将不胜感激。
InMemoryConnection
更适合个体 request/response 而不是存根多个不同的 requests/responses,但是,可以从中派生出 IConnection
来实现此目的
public class TestConnection : InMemoryConnection
{
private (byte[], int, string) DetermineResponse(RequestData requestData)
{
byte[] responseBody = null;
int statusCode = 200;
string contentType = RequestData.MimeType;
// do the switching here e.g. ctor might take a dictionary of Predicate<RequestData> -> Responses
if (requestData.Uri.AbsolutePath == "/_search")
{
responseBody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { }));
}
return (responseBody, statusCode, contentType);
}
public override TResponse Request<TResponse>(RequestData requestData)
{
var (responseBody, statusCode, contentType) = DetermineResponse(requestData);
return base.ReturnConnectionStatus<TResponse>(requestData, responseBody, statusCode, contentType);
}
public override Task<TResponse> RequestAsync<TResponse>(RequestData requestData, CancellationToken cancellationToken)
{
var (responseBody, statusCode, contentType) = DetermineResponse(requestData);
return base.ReturnConnectionStatusAsync<TResponse>(requestData, cancellationToken, responseBody, statusCode, contentType);
}
}
像这样的东西可能是对 Elasticsearch.Net.VirtualizedCluster 的一个很好的补充。
Similar issue is when verifying calls to Elasticsearch. I can use
OnRequestCompleted to set a couple of booleans like this:
OnRequestCompleted(response => {
if (response.Uri.ToString().Contains("/blabla/_search")) {}
else if (response.HttpMethod == HttpMethod.POST && response.Success &&
response.Uri.ToString().StartsWith("http://localhost:9200/blabla"))
wasCalled = true;
else // We don't expect any other calls
failed = true; })
与其在 OnRequestCompleted
中断言这些,我宁愿
- 记录
TestConnection
中的调用并断言它们是在那里调用的。不过,我想知道是否可以通过某种方式从响应中推断出以这种方式断言的内容。
或
- 对
response.ApiCall
进行断言
我正在从对 Elasticsearch 的模拟调用(通过 NEST)转向使用 InMemoryConnection
class 和一些硬编码的 JSON 来模拟真实的 Elasticsearch 响应来自C# 代码。效果很好,比 mock 好得多,mock 需要对 NEST 的实现方式有深刻的理解和知识,而且很容易出错。
我的问题是,如果我想模拟对 Elasticsearch 的多次调用,我看不到任何简单的方法。 InMemoryConnection
仅接受单个 JSON 字符串:
var connection = new InMemoryConnection(Encoding.UTF8.GetBytes(json));
最好是这样说,return 第一次通话时为 x,第二次通话时为 y。
类似的问题出现在验证对 Elasticsearch 的调用时。我可以使用 OnRequestCompleted
设置几个布尔值,如下所示:
OnRequestCompleted(response =>
{
if (response.Uri.ToString().Contains("/blabla/_search")) {}
else if (response.HttpMethod == HttpMethod.POST && response.Success && response.Uri.ToString().StartsWith("http://localhost:9200/blabla"))
wasCalled = true;
else // We don't expect any other calls
failed = true;
})
对这些布尔值进行断言时。但这感觉不对。
如有任何想法,我们将不胜感激。
InMemoryConnection
更适合个体 request/response 而不是存根多个不同的 requests/responses,但是,可以从中派生出 IConnection
来实现此目的
public class TestConnection : InMemoryConnection
{
private (byte[], int, string) DetermineResponse(RequestData requestData)
{
byte[] responseBody = null;
int statusCode = 200;
string contentType = RequestData.MimeType;
// do the switching here e.g. ctor might take a dictionary of Predicate<RequestData> -> Responses
if (requestData.Uri.AbsolutePath == "/_search")
{
responseBody = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { }));
}
return (responseBody, statusCode, contentType);
}
public override TResponse Request<TResponse>(RequestData requestData)
{
var (responseBody, statusCode, contentType) = DetermineResponse(requestData);
return base.ReturnConnectionStatus<TResponse>(requestData, responseBody, statusCode, contentType);
}
public override Task<TResponse> RequestAsync<TResponse>(RequestData requestData, CancellationToken cancellationToken)
{
var (responseBody, statusCode, contentType) = DetermineResponse(requestData);
return base.ReturnConnectionStatusAsync<TResponse>(requestData, cancellationToken, responseBody, statusCode, contentType);
}
}
像这样的东西可能是对 Elasticsearch.Net.VirtualizedCluster 的一个很好的补充。
Similar issue is when verifying calls to Elasticsearch. I can use OnRequestCompleted to set a couple of booleans like this:
OnRequestCompleted(response => { if (response.Uri.ToString().Contains("/blabla/_search")) {} else if (response.HttpMethod == HttpMethod.POST && response.Success && response.Uri.ToString().StartsWith("http://localhost:9200/blabla")) wasCalled = true; else // We don't expect any other calls failed = true; })
与其在 OnRequestCompleted
中断言这些,我宁愿
- 记录
TestConnection
中的调用并断言它们是在那里调用的。不过,我想知道是否可以通过某种方式从响应中推断出以这种方式断言的内容。
或
- 对
response.ApiCall
进行断言