我写了一堆查询来进行elasticsearch,我想为它们写一个单元测试。使用此后最小的量,可以进行弹性连接,从而可以进行一般的模拟。但是,当我尝试查看由查询生成的Json时,我没有设法以任何方式获取它。我试图按照这个帖子elsatic查询起订量,但它是只与旧版本的巢的,因为该方法ConnectionStatus并RequestInformation不再为ISearchResponse对象。
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** }
还有其他方法可以实现我的要求吗?
最好的方法是使用InMemoryConnection捕获请求字节并将其与期望的JSON比较。这就是单元测试NEST所做的。就像是
InMemoryConnection
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搜索,您不太可能会遇到某些事情,但是需要注意。
JObject.DeepEquals(...)
true
如果您要进行许多测试检查序列化,则需要创建一个实例ConnectionSettings并与所有人共享,以便可以利用其中的内部缓存,并且测试将比实例化新实例更快。在每个测试中。
ConnectionSettings