首页 文章

ElasticSearch NEST 5.6.1查询单元测试

提问于
浏览
1

我为弹性搜索写了一堆查询,我想为它们编写一个单元测试 . 使用这篇文章moq an elastic connection我能够进行一般的 Mock . 但是当我试图查看从我的查询生成的Json时,我无法以任何方式获得它 . 我试着关注这篇文章elsatic query moq,但它仅与旧版本的Nest相关,因为方法 ConnectionStatusRequestInformation 不再可用于 ISearchResponse 对象 .

我的测试看起来如下:

[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**
}

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

1 回答

  • 1

    执行此操作的最佳方法是使用 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对象中存在重复的对象键,Json.NET的 JObject.DeepEquals(...) 也将返回 true (只要最后一个键/值匹配) . 如果您只是序列化NEST搜索,它会遇到's not likely something you'll,但需要注意的事项 .

    如果您想要创建 ConnectionSettings 的单个实例并与所有共享,那么您可以利用其中的内部缓存,并且您的测试将比在每个测试中实例化一个新实例更快地运行 .

相关问题