ElasticSearch NEST 5.6.1 单元测试的查询

2023-12-02

我向弹性搜索编写了一堆查询,我想为它们编写一个单元测试。使用这篇文章最小起订量弹性连接我能够进行一般性的嘲笑。但是当我尝试查看从查询生成的 Json 时,我没有设法以任何方式获取它。 我尝试关注这篇文章弹性查询最小起订量,但它仅与旧版本的 Nest 相关,因为该方法ConnectionStatus and RequestInformation不再适用于ISearchResponse object.

我的测试如下:

[TestMethod]
 public void VerifyElasticFuncJson()
{
//Arrange
var elasticService = new Mock<IElasticService>();
var elasticClient = new Mock<IElasticClient>();
var clinet = new ElasticClient();
var searchResponse = new Mock<ISearchResponse<ElasticLog>>();
elasticService.Setup(es => es.GetConnection())
    .Returns(elasticClient.Object);

elasticClient.Setup(ec => ec.Search(It.IsAny<Func<SearchDescriptor<ElasticLog>, 
                          ISearchRequest>>())).
                          Returns(searchResponse.Object);

//Act
var service = new ElasticCusipInfoQuery(elasticService.Object);
var FindFunc = service.MatchCusip("CusipA", HostName.GSMSIMPAPPR01, 
                                        LogType.Serilog);
var con = GetConnection();
var search =  con.Search<ElasticLog>(sd => sd
             .Type(LogType.Serilog)
             .Index("logstash-*")
             .Query(q => q
             .Bool(b => b
                    .Must(FindFunc)
                    )
               )     
             );
 **HERE I want to get the JSON** and assert it look as expected**
}

还有其他方法可以实现我的要求吗?


最好的方法是使用InMemoryConnection捕获请求字节并将其与预期的 JSON 进行比较。这就是 NEST 单元测试的作用。就像是

private static void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection())
        .DefaultIndex("default")
        .DisableDirectStreaming();

    var client = new ElasticClient(connectionSettings);

    // Act
    var searchResponse = client.Search<Question>(s => s
       .Query(q => (q
         .Match(m => m
               .Field(f => f.Title)
               .Query("Kibana")
         ) || q
         .Match(m => m
               .Field(f => f.Title)
               .Query("Elasticsearch")
               .Boost(2)
         )) && +q
         .Range(t => t
               .Field(f => f.Score)
               .GreaterThan(0)
         )
       )
    );
    
    var actual = searchResponse.RequestJson();

    var expected = new 
    {
        query = new {
            @bool = new {
                must = new object[] {
                    new {
                        @bool = new {
                            should = new object[] {
                                new {
                                    match = new {
                                        title = new {
                                            query = "Kibana"
                                        }
                                    }
                                },
                                new {
                                    match = new {
                                        title = new {
                                            query = "Elasticsearch",
                                            boost = 2d
                                        }
                                    }
                                }
                            },
                        }
                    },
                    new {
                        @bool = new {
                            filter = new [] {
                                new {
                                    range = new {
                                        score = new {
                                            gt = 0d
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    };

    // Assert
    Console.WriteLine(JObject.DeepEquals(JToken.FromObject(expected), JToken.Parse(actual)));
}

public static class Extensions
{
    public static string RequestJson(this IResponse response) =>
        Encoding.UTF8.GetString(response.ApiCall.RequestBodyInBytes);
}

我对预期的 JSON 使用了匿名类型,因为它比转义的 JSON 字符串更容易使用。

需要注意的一件事是 Json.NET 的JObject.DeepEquals(...)将返回true即使 JSON 对象中有重复的对象键(只要最后一个键/值匹配)。如果您只是序列化 NEST 搜索,则不太可能遇到这种情况,但需要注意。

如果您要进行许多测试来检查序列化,则需要创建一个实例ConnectionSettings并与所有人共享,以便您可以利用其中的内部缓存,并且您的测试将比在每个测试中实例化新实例运行得更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ElasticSearch NEST 5.6.1 单元测试的查询 的相关文章

随机推荐