测试ASP.NET Core IMemoryCache的正确方法

编程入门 行业动态 更新时间:2024-10-26 23:34:53
本文介绍了测试ASP.NET Core IMemoryCache的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在编写一个简单的测试用例,用于测试控制器在调用服务之前是否调用了缓存.我正在使用xUnit和Moq来完成任务.

I'm writing a simple test case that tests that my controller calls the cache before calling my service. I'm using xUnit and Moq for the task.

我遇到了一个问题,因为GetOrCreateAsync<T>是扩展方法,并且框架无法对其进行嘲笑.我依靠内部细节来弄清楚我可以模拟TryGetValue并逃避我的测试(请参阅 github/aspnet/Caching/blob/c432e5827e4505c05ac7ad8ef1e3bc6bf784520b/src/Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs#L116 )

I'm facing an issue because GetOrCreateAsync<T> is an extension method, and those can't be mocked by the framework. I relied on internal details to figure out I can mock TryGetValue instead and get away with my test (see github/aspnet/Caching/blob/c432e5827e4505c05ac7ad8ef1e3bc6bf784520b/src/Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs#L116)

[Theory, AutoDataMoq] public async Task GivenPopulatedCacheDoesntCallService( Mock<IMemoryCache> cache, SearchRequestViewModel input, MyViewModel expected) { object expectedOut = expected; cache .Setup(s => s.TryGetValue(input.Serialized(), out expectedOut)) .Returns(true); var sut = new MyController(cache.Object, Mock.Of<ISearchService>()); var actual = await sut.Search(input); Assert.Same(expected, actual); }

我无法满足于我正在查看MemoryCache实现细节的事实,并且它随时可能发生变化.

I can't sleep with the fact that I'm peeking into the MemoryCache implementation details and it can change at any point.

作为参考,这是SUT代码:

For reference, this is the SUT code:

public async Task<MyViewModel> Search(SearchRequestViewModel request) { return await cache.GetOrCreateAsync(request.Serialized(), (e) => search.FindAsync(request)); }

您是否建议进行其他测试?

Would you recommend testing any differently?

推荐答案

老实说,我建议完全不测试此交互.

To be honest I would recommend not to test this interaction at all.

我对这个测试用例的处理方式有所不同:您真正关心的是,一旦控制器从ISearchService检索到数据,它就不会再次请求数据,而应该返回上一次调用的结果.

I would approach this test case a bit differently: what you really care about is that once your controller retrieved data from your ISearchService it shouldn't request the data again and should return the result from the previous call.

在幕后使用IMemoryCache的事实只是实现细节.我什至不用为它设置测试倍数,我只会使用Microsoft.Extensions.Caching.Memory.MemoryCache对象的实例.

The fact that an IMemoryCache is used behind the scenes is just an implementation detail. I wouldn't even bother setting up a test double for it, I would just use an instance of the Microsoft.Extensions.Caching.Memory.MemoryCache object.

我的新测试看起来像这样:

My new test would look something like this:

[Theory] public async Task GivenResultAlreadyRetrieved_ShouldNotCallServiceAgain() { // Arrange var expected = new MyViewModel(); var cache = new MemoryCache(new MemoryCacheOptions()); var searchService = new Mock<ISearchService>(); var input = new SearchRequestViewModel(); searchService .SetupSequence(s => s.FindAsync(It.IsAny<SearchRequestViewModel>())) .Returns(Task.FromResult(expected)) .Returns(Task.FromResult(new MyViewModel())); var sut = new MyController(cache, searchService.Object); // Act var resultFromFirstCall = await sut.Search(input); var resultFromSecondCall = await sut.Search(input); // Assert Assert.Same(expected, resultFromFirstCall); Assert.Same(expected, resultFromSecondCall); }

更多推荐

测试ASP.NET Core IMemoryCache的正确方法

本文发布于:2023-11-13 21:40:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1585392.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:正确   测试   方法   ASP   Core

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!