使用InMemoryConnection测试ElasticSearch

我正在尝试围绕我们使用ElasticSearch(在C#中使用Nest 1.4.2)添加测试,并希望使用InMemoryConnection,但我遗漏了一些东西(我假设)并且没有成功。

我已经创建了这个简单的Nunit测试用例,作为我的问题的一个简单示例

using System; using Elasticsearch.Net.Connection; using FluentAssertions; using Nest; using NUnit.Framework; namespace NestTest { public class InMemoryConnections { public class TestThing { public string Stuff { get; } public TestThing(string stuff) { Stuff = stuff; } } [Test] public void CanBeQueried() { var connectionSettings = new ConnectionSettings(new Uri("http://foo.test"), "default_index"); var c = new ElasticClient(connectionSettings, new InMemoryConnection(connectionSettings)); c.Index(new TestThing("peter rabbit")); var result = c.Search(sd => sd); result.ConnectionStatus.Success.Should().BeTrue(); } } } 

查询成功但找不到我刚编入索引的文档…

如果我更新到NEST版本2.3.3和新语法

  [Test] public void CanBeQueried() { var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); var settings = new ConnectionSettings(connectionPool, new InMemoryConnection()); settings.DefaultIndex("default"); var c = new ElasticClient(settings); c.Index(new TestThing("peter rabbit")); var result = c.Search(sd => sd); result.CallDetails.Success.Should().BeTrue(); result.Documents.Single().Stuff.Should().Be("peter rabbit"); } 

它以同样的方式失败…即查询报告为成功但返回0文档

InMemoryConnection实际上并不发送任何请求或从Elasticsearch接收任何响应 ; 与连接设置上的.SetConnectionStatusHandler()一起使用(或NEST 2.x +中的.OnRequestCompleted() ),这是查看序列化请求forms的便捷方式。

当不使用InMemoryConnection但仍然设置.SetConnectionStatusHandler().OnRequestCompleted() ,根据NEST版本,当NEST 1.x或.DisableDirectStreaming()也设置了.ExposeRawResponse(true)时,它也是查看响应的便捷方式。 .DisableDirectStreaming()分别在NEST 2.x +中设置。

NEST 1.x的一个例子

 void Main() { var settings = new ConnectionSettings(new Uri("http://localhost:9200")) .ExposeRawResponse(true) .PrettyJson() .SetDefaultIndex("myIndexName") .MapDefaultTypeNames(d => d.Add(typeof(myPoco), string.Empty)) .SetConnectionStatusHandler(r => { // log out the requests if (r.Request != null) { Console.WriteLine("{0} {1} \n{2}\n", r.RequestMethod.ToUpperInvariant(), r.RequestUrl, Encoding.UTF8.GetString(r.Request)); } else { Console.WriteLine("{0} {1}\n", r.RequestMethod.ToUpperInvariant(), r.RequestUrl); } Console.WriteLine(); if (r.ResponseRaw != null) { Console.WriteLine("Status: {0}\n{1}\n\n{2}\n", r.HttpStatusCode, Encoding.UTF8.GetString(r.ResponseRaw), new String('-', 30)); } else { Console.WriteLine("Status: {0}\n\n{1}\n", r.HttpStatusCode, new String('-', 30)); } }); var client = new ElasticClient(settings, new InMemoryConnection()); int skipCount = 0; int takeSize = 100; var searchResults = client.Search(x => x .Query(q => q .Bool(b => b .Must(m => m.Match(mt1 => mt1.OnField(f1 => f1.status).Query("New"))))) .Skip(skipCount) .Take(takeSize) ); } public class myPoco { public string status { get; set;} } 

产量

 POST http://localhost:9200/myIndexName/_search?pretty=true { "from": 0, "size": 100, "query": { "bool": { "must": [ { "match": { "status": { "query": "New" } } } ] } } } Status: 0 { "USING NEST IN MEMORY CONNECTION" : null } ------------------------------ 

而对于NEST 2.x

 void Main() { var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); var defaultIndex = "default-index"; var connectionSettings = new ConnectionSettings(pool, new InMemoryConnection()) .DefaultIndex(defaultIndex) .PrettyJson() .DisableDirectStreaming() .OnRequestCompleted(response => { // log out the request if (response.RequestBodyInBytes != null) { Console.WriteLine( $"{response.HttpMethod} {response.Uri} \n" + $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}"); } else { Console.WriteLine($"{response.HttpMethod} {response.Uri}"); } Console.WriteLine(); // log out the response if (response.ResponseBodyInBytes != null) { Console.WriteLine($"Status: {response.HttpStatusCode}\n" + $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" + $"{new string('-', 30)}\n"); } else { Console.WriteLine($"Status: {response.HttpStatusCode}\n" + $"{new string('-', 30)}\n"); } }); var client = new ElasticClient(connectionSettings); int skipCount = 0; int takeSize = 100; var searchResults = client.Search(x => x .Query(q => q .Bool(b => b .Must(m => m.Match(mt1 => mt1.Field(f1 => f1.status).Query("New"))))) .Skip(skipCount) .Take(takeSize) ); } 

您当然可以使用您最喜欢的模拟框架从客户端模拟/存根响应,并且取决于客户端接口, IElasticClient ,如果这是您想要采用的路由,尽管断言请求的序列化forms符合您在SUT中的期望可能是足够。