使用 C# Moq 模拟 ElasticSearch 客户端
Mocking an ElasticSearch client using C# Moq
我正在测试我的 class ElasticUtility
,它需要一个 ElasticClient
的实例才能正常工作,所以我模拟了这样的 class 并将其注入到ElasticUtility
实例 (utility
)
private ElasticUtility utility;
private Mock<IElasticClient> elasticClientMock;
private string elasticSearchIndexName;
elasticClientMock = new Mock<IElasticClient>();
utility = new UhhElasticUtility(elasticClientMock.Object);
这是实际测试代码:
[Test]
public void GetGetPvDataClientReturnNull()
{
// arrange
var groupId = "groupid";
var startTime = new DateTime(2015, 08, 17, 13, 30, 00);
var endTime = new DateTime(2015, 08, 17, 13, 40, 00);
// act
utility.GetPvData(groupId, startTime, endTime);
// assert
elasticClientMock.Verify(ec => ec.Search<SegmentRecord>(It.IsAny<Nest.ISearchRequest>()), Times.Once());
}
当 Moq 库在模拟的 ElastiClient
.
中调用 .Search()
方法时,我得到一个 Null 引用异常
编辑:
ElasticUtility
的构造函数:
protected ElasticUtility(IElasticClient elasticClient, string elasticIndexName)
{
this.ElasticClient = elasticClient;
this.ElasticIndexName = elasticIndexName;
}
编辑:GetPvData
() 方法:
public IEnumerable<dynamic> GetPvData(string groupId, DateTime startTime, DateTime endTime)
{
var res = ElasticClient.Search<SegmentRecord>(s => s
.Index(ElasticIndexName)
.Filter(f =>
f.Term(t => t.HistoryId, groupId) &&
f.Range(i =>
i.OnField(a => a.DateTime).LowerOrEquals(startTime))).SortAscending(p => p.DateTime).Size(1)).Documents.ToList();
return res.ToArray();
}
发生 NullReferenceException
是因为您没有在 search
方法上指定行为。您的 search
方法 returns null 然后您调用 .Document
null。
指定行为的方式如下:
elasticClientMock.Setup(x => x.Search<SegmentRecord>(
It.IsAny</* put here the right Func */>))
.Returns( /* put here the instance you want to return */);
你必须用正确的类型替换我的评论。
代码来自 .git 此处:https://gist.github.com/netoisc/5d456850d79f246685fee23be2469155
var people = new List<Person>
{
new Person { Id = 1 },
new Person { Id = 2 },
};
var hits = new List<IHit<Person>>
{
new Mock<IHit<Person>>().Object
};
var mockSearchResponse = new Mock<ISearchResponse<Person>>();
mockSearchResponse.Setup(x => x.Documents).Returns(people);
mockSearchResponse.Setup(x => x.Hits).Returns(hits);
var mockElasticClient = new Mock<IElasticClient>();
mockElasticClient.Setup(x => x
.Search(It.IsAny<Func<SearchDescriptor<Person>, ISearchRequest>>()))
.Returns(mockSearchResponse.Object);
我正在测试我的 class ElasticUtility
,它需要一个 ElasticClient
的实例才能正常工作,所以我模拟了这样的 class 并将其注入到ElasticUtility
实例 (utility
)
private ElasticUtility utility;
private Mock<IElasticClient> elasticClientMock;
private string elasticSearchIndexName;
elasticClientMock = new Mock<IElasticClient>();
utility = new UhhElasticUtility(elasticClientMock.Object);
这是实际测试代码:
[Test]
public void GetGetPvDataClientReturnNull()
{
// arrange
var groupId = "groupid";
var startTime = new DateTime(2015, 08, 17, 13, 30, 00);
var endTime = new DateTime(2015, 08, 17, 13, 40, 00);
// act
utility.GetPvData(groupId, startTime, endTime);
// assert
elasticClientMock.Verify(ec => ec.Search<SegmentRecord>(It.IsAny<Nest.ISearchRequest>()), Times.Once());
}
当 Moq 库在模拟的 ElastiClient
.
.Search()
方法时,我得到一个 Null 引用异常
编辑:
ElasticUtility
的构造函数:
protected ElasticUtility(IElasticClient elasticClient, string elasticIndexName)
{
this.ElasticClient = elasticClient;
this.ElasticIndexName = elasticIndexName;
}
编辑:GetPvData
() 方法:
public IEnumerable<dynamic> GetPvData(string groupId, DateTime startTime, DateTime endTime)
{
var res = ElasticClient.Search<SegmentRecord>(s => s
.Index(ElasticIndexName)
.Filter(f =>
f.Term(t => t.HistoryId, groupId) &&
f.Range(i =>
i.OnField(a => a.DateTime).LowerOrEquals(startTime))).SortAscending(p => p.DateTime).Size(1)).Documents.ToList();
return res.ToArray();
}
发生 NullReferenceException
是因为您没有在 search
方法上指定行为。您的 search
方法 returns null 然后您调用 .Document
null。
指定行为的方式如下:
elasticClientMock.Setup(x => x.Search<SegmentRecord>(
It.IsAny</* put here the right Func */>))
.Returns( /* put here the instance you want to return */);
你必须用正确的类型替换我的评论。
代码来自 .git 此处:https://gist.github.com/netoisc/5d456850d79f246685fee23be2469155
var people = new List<Person>
{
new Person { Id = 1 },
new Person { Id = 2 },
};
var hits = new List<IHit<Person>>
{
new Mock<IHit<Person>>().Object
};
var mockSearchResponse = new Mock<ISearchResponse<Person>>();
mockSearchResponse.Setup(x => x.Documents).Returns(people);
mockSearchResponse.Setup(x => x.Hits).Returns(hits);
var mockElasticClient = new Mock<IElasticClient>();
mockElasticClient.Setup(x => x
.Search(It.IsAny<Func<SearchDescriptor<Person>, ISearchRequest>>()))
.Returns(mockSearchResponse.Object);