相关疑难解决方法(0)

模拟IMemoryCache与Moq抛出异常

我正试图IMemoryCache用Moq 嘲笑.我收到这个错误:

Moq.dll中出现"System.NotSupportedException"类型的异常,但未在用户代码中处理

附加信息:表达式引用不属于模拟对象的方法:x => x.Get <String>(It.IsAny <String>())

我的嘲弄代码:

namespace Iag.Services.SupplierApiTests.Mocks
{
    public static class MockMemoryCacheService
    {
        public static IMemoryCache GetMemoryCache()
        {
            Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>();
            mockMemoryCache.Setup(x => x.Get<string>(It.IsAny<string>())).Returns("");<---------- **ERROR**
            return mockMemoryCache.Object;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么我会收到这个错误?

这是测试中的代码:

var cachedResponse = _memoryCache.Get<String>(url);
Run Code Online (Sandbox Code Playgroud)

哪种_memoryCache类型IMemoryCache

我如何模拟_memoryCache.Get<String>(url)上面的内容并让它返回null?

编辑:我怎么做同样的事情,但为 _memoryCache.Set<String>(url, response);?我不介意它返回什么,我只需要将方法添加到mock中,这样它就不会在调用时抛出.

我试着回答这个问题的答案:

mockMemoryCache
    .Setup(m => m.CreateEntry(It.IsAny<object>())).Returns(null as ICacheEntry);
Run Code Online (Sandbox Code Playgroud)

因为在memoryCache扩展中它显示它CreateEntry在内部使用Set.但是"对象引用没有设置为对象的实例"是错误的.

c# unit-testing moq .net-core asp.net-core

16
推荐指数
3
解决办法
6388
查看次数

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

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

我面临一个问题,因为它GetOrCreateAsync<T>是一种扩展方法,并且不能被框架嘲笑.我依靠内部细节来弄清楚我可以嘲笑TryGetValue并躲开我的测试(参见https://github.com/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);
}
Run Code Online (Sandbox Code Playgroud)

我无法入睡,因为我正在窥视MemoryCache实现细节,它可以在任何时候改变.

作为参考,这是SUT代码:

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

您会建议以不同方式进行测试吗

c# extension-methods moq .net-core asp.net-core

13
推荐指数
1
解决办法
8033
查看次数

XUnit 如何模拟 IMemoryCache ASP.NET Core

我知道 IMemoryCache.Set 是一个扩展方法,所以它不能被嘲笑。人们已经为这种情况提供了解决方法,例如 NKosi在这里提供的解决方法。我想知道如何为我的数据访问层实现这一点,其中我的 MemoryCache 返回一个值,当找不到它时,它从数据库中获取数据,将其设置为 MemoryCache 并返回所需的值。

    public string GetMessage(int code)
    {
        if(myMemoryCache.Get("Key") != null)
        {
            var messages= myMemoryCache.Get<IEnumerable<MyModel>>("Key");
            return messages.Where(x => x.Code == code).FirstOrDefault().Message;
        }

        using (var connection = dbFactory.CreateConnection())
        {
            var cacheOptions = new MemoryCacheEntryOptions { SlidingExpiration = TimeSpan.FromHours(1) };
            const string sql = @"SELECT Code, Message FROM MyTable";

            var keyPairValueData = connection.Query<KeyPairValueData>(sql);

            myMemoryCache.Set("Key", keyPairValueData, cacheOptions );

            return keyPairValueData.Where(x => x.Code == code).FirstOrDefault().Message;
        }
    }
Run Code Online (Sandbox Code Playgroud)

以下是我的单元测试 - 当然它不起作用,因为我无法模拟 IMemoryCache

    [Fact]
    public void GetMessage_ReturnsString()
    {
        //Arrange …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing moq mocking xunit

3
推荐指数
1
解决办法
3418
查看次数