如何模拟IElasticClient的Get方法?

问题描述 投票:0回答:2

这是我的类的最小重现,它通过Nest 1.7处理与Elasticsearch的通信。

public class PeopleRepository
{
    private IElasticClient client;

    public PeopleRepository(IElasticClient client)
    {
        this.client = client;
    }

    public Person Get(string id)
    {
        var getResponse = client.Get<Person>(p => p.Id(id));

        // Want to test-drive this change:
        if (getResponse.Source == null) throw new Exception("Person was not found for id: " + id);

        return getResponse.Source;
    }
}

正如代码中提到的,我想测试一下某个变化。我使用NUnit 2.6.4和Moq 4.2来尝试做这件事,方式如下。

[Test]
public void RetrieveProduct_WhenDocNotFoundInElastic_ThrowsException()
{
    var clientMock = new Mock<IElasticClient>();
    var getSelectorMock = It.IsAny<Func<GetDescriptor<Person>, GetDescriptor<Person>>>();
    var getRetvalMock = new Mock<IGetResponse<Person>>();

    getRetvalMock
        .Setup(r => r.Source)
        .Returns((Person)null);

    clientMock
        .Setup(c => c.Get<Person>(getSelectorMock))
        .Returns(getRetvalMock.Object);

    var repo = new PeopleRepository(clientMock.Object);

    Assert.Throws<Exception>(() => repo.Get("invalid-id"));
}

然而,我对ElasticClient的各个位进行了错误的模拟: Get 办法 IElasticClient 返回null,从而导致NullReferenceException在 getResponse.Source 在我的代码抛出我想抛出的异常之前。

我如何正确地模拟 Get<T> 办法 IElasticClient?

c# unit-testing elasticsearch moq nest
2个回答
5
投票

你不能使用 It.IsAny 方法之外的 Setup 调用,否则会将其视为空。移动 It.IsAny 到设置中,应该是可以的。

 clientMock
        .Setup(c => c.Get<Person>(It.IsAny<Func<GetDescriptor<Person>, GetDescriptor<Person>>>()))
        .Returns(getRetvalMock.Object);
© www.soinside.com 2019 - 2024. All rights reserved.