在 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 中断言这些,我宁愿

  1. 记录 TestConnection 中的调用并断言它们是在那里调用的。不过,我想知道是否可以通过某种方式从响应中推断出以这种方式断言的内容。

  1. response.ApiCall
  2. 进行断言