最好的方法是使用
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
与所有人共享,以便您可以利用其中的内部缓存,并且您的测试将比在每个测试中实例化新实例运行得更快。