使用Nest在C#中进行Elasticsearch测试(单元/集成)最佳实践

joh*_*yka 4 testing elasticsearch nest

我一直在搜索我应该如何测试我的数据访问层而不是很成功.让我列出我的担忧:

  1. 单元测试

这个人(这里:使用InMemoryConnection测试ElasticSearch)说:

虽然声明序列化形式的请求符合您在SUT中的期望可能就足够了.

断言请求的序列化形式是否真的值得?这些测试有什么价值吗?它似乎不太可能改变不应该更改序列化请求的函数.

如果值得,那么断言这些要求的正确方法是什么?

  1. 再次进行单元测试

另一个人(这里:使用MOQ的ElasticSearch 2.0 Nest Unit Testing)显示了一个好看的例子:

void Main()
{
    var people = new List<Person>
    {
        new Person { Id = 1 },
        new Person { Id = 2 },
    };

    var mockSearchResponse = new Mock<ISearchResponse<Person>>();
    mockSearchResponse.Setup(x => x.Documents).Returns(people);

    var mockElasticClient = new Mock<IElasticClient>();
    mockElasticClient.Setup(x => x
        .Search(It.IsAny<Func<SearchDescriptor<Person>, ISearchRequest>>()))
        .Returns(mockSearchResponse.Object);

    var result = mockElasticClient.Object.Search<Person>(s => s);

    Assert.AreEqual(2, result.Documents.Count()).Dump();
}

public class Person
{
    public int Id { get; set;}
}
Run Code Online (Sandbox Code Playgroud)

可能我错过了一些东西,但我看不出这段代码的重点.首先,他嘲笑一个ISearchResponse总是返回people列表.然后他嘲笑一个IElasticClient将之前的搜索响应返回给他所做的任何搜索请求.

那么在那之后断言是真的并不让我感到惊讶.这类测试有什么意义?

  1. 集成测试

对我来说,集成测试对测试数据访问层更有意义.所以经过一番搜索,我找到了这个(https://www.nuget.org/packages/elasticsearch-inside/)包.如果我没有弄错,这只是一个嵌入式JVM和ES.使用它是一个好习惯吗?我不应该使用我已经运行的实例吗?

如果有人对我没有包括的测试有很好的经验,我也很乐意听到这些.

Rus*_*Cam 8

您列出的每种方法都可能是一种合理的方法,具体取决于您尝试通过测试实现的目标.你没有在你的问题中指明这个:)

让我们回顾一下您列出的选项

  1. 如果您根据不同数量的输入构建对Elasticsearch的请求,则将请求的序列化形式断言给Elasticsearch可能是一种充分的方法.您可能拥有提供不同输入实例的测试,并断言将为每个实例发送到Elasticsearch的查询形式.这些类型的测试将很快执行,但会假设生成的查询和您声明的形式将返回您期望的结果.
  2. 这是另一种单元测试形式,它将与Elasticsearch客户端的交互存根.此示例中的被测系统(SUT)不是客户端,而是内部使用客户端的另一个组件,因此通过存根对象控制与客户端的交互以返回预期响应.这个例子的设计是因为在一个真实的测试中,你不会在你指出客户端调用的结果时断言,而是在SUT的输出上断言.
  3. 针对Elasticsearch集群中已知数据集的集成/行为测试可以提供最大价值并超越第1点和第2点,因为它们不仅会偶然测试针对给定输入发送到Elasticsearch的生成查询,还会测试交互并产生预期的结果.然而,毫无疑问,这些类型的测试比1和2更难设置,但是设置的投资可能会超过它们对您项目的好处.

因此,您需要问自己哪些类型的测试足以达到您要求断言您的系统正在按预期执行的操作所需的保证级别; 对于系统的不同元素,它可以是所有三种不同方法的组合.

您可能想要查看.NET客户端本身的测试方式 ; 有测试项目中的部件旋转起来的Elasticsearch簇安装不同的插件,与已知的生成的数据种子它并作出对结果的断言.源代码是在Apache 2.0许可下开放和许可的,因此可以随意使用项目中的元素:)

  • 您可以将预期和实际的json字符串反序列化为Json.NET`Jobject`实例,然后使用`JObject.DeepEquals()` - http://www.newtonsoft.com/json/help/html/DeepEquals.htm.请记住,对"JObject"的反序列化会忽略重复的json属性名称(无论如何都不应该是有效的json) (3认同)