代码之家  ›  专栏  ›  技术社区  ›  Green Moshe

ElasticSearch Nest 5.6.1单元测试查询

  •  1
  • Green Moshe  · 技术社区  · 8 年前

    我写了一堆查询到弹性搜索,我想为它们编写一个单元测试。使用此帖子 moq an elastic connection 我能做一个一般的嘲笑。但是当我试图查看从我的查询生成的json时,我没有设法以任何方式获取它。 我试着跟踪这个帖子 elsatic query moq ,但它只与旧版本的nest相关,因为 ConnectionStatus RequestInformation 不再适用于 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 回复  |  直到 8 年前
        1
  •  1
  •   Russ Cam    8 年前

    最好的方法是使用 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对象中有重复的对象键(只要最后一个键/值匹配)。不过,如果你只是将巢穴搜索序列化,就不太可能遇到这种情况,而是需要注意的事情。

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