从集成测试中植入种子时,.NET Core 3.1 IMemoryCache为空

如何解决从集成测试中植入种子时,.NET Core 3.1 IMemoryCache为空

问题在于,由于搜索复杂,因此使用Entity Framework Core 3.1IMemoryCache的Web API。示例存储库:

public class UserRepository : IUserRepository
{
    private readonly IMemoryCache _cache;
    private readonly ApplicationDbContext _dbContext;

    public UserRepository(IMemoryCache cache,ApplicationDbContext dbContext)
    {
        _cache = cache;
        _dbContext = dbContext;
    }

    public async Task<List<UserCacheModel>> GetAll()
    {
        List<User> users = _cache.Get<List<User>>("users");
        if (users != null)
        {
            return UserMapper.MapToCacheModelList(users);
        }
        return await _dbContext.Users.ToListAsync();
    }

    public async Task<int> Insert(User user)
    {
        // Add to database
        _dbContext.Users.Add(user);
        await _dbContext.SaveChangesAsync();

        // Add to cache
        List<UserCacheModel> cachedUsers = _cache.Get<List<UserCacheModel>>("users");
        cachedUsers.Add(UserMapper.MapToCacheModel(user));
        }
    }

这是一个非常简单的示例,但是它使您清楚地知道如何使用它。为了进行复杂的测试,测试项目中有一个自定义的Web应用程序工厂,该工厂使用Startup.cs配置webhost,DI和所有内容。显然,DbContext已从DI中删除,并通过In-Memory DB切换到EF Core 3.1

问题是我想在此自定义Web应用程序工厂中植入应用内Memory Cache。它工作正常,但是当测试尝试插入用户时,它失败,因为 List<UserCacheModel> cachedUsers = _cache.Get<List<UserCacheModel>>("users");此行将为空。从Web应用程序工厂中植入的MemoryCache似乎与从DI中的UserRepository中解析的实例不同。

但是,如果我从工厂范围手动解析IMemoryCache,则可以看到启动时播种的数据。 DbContext已正确播种,除此以外一切正常

更新:

通过创建Microsoft.AspNetCore.Mvc.Testing自定义实现,通过WebApplicationFactory命名空间运行集成测试。这将创建一个Web应用程序,就像您调试自己的API时一样,因此,当您调用带有保存用户的请求的ActionMethod时,IMemoryCache是应用程序内缓存该新创建的Web应用程序就像一个docker容器,与您从集成测试代码中解析的应用程序不同。

至少我现在是这样想的。

有什么想法是最好的方法来获得应用内cache而不在应用中创建仅用于测试目的的假控制器?

解决方法

考虑在创建 WebApplicationFactory 后设置缓存,如下所示:

var factory = new MyWebApplicationFactory<Startup>();
var queriesClient = factory.CreateClient();
using var scope = factory.Services.CreateScope();
var memCache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();
memCache.Set("Key",Value);

using HttpResponseMessage response = await queriesClient.GetAsync(new Uri(requestUri));

这将直接在工厂范围内设置缓存,现在就可以使用了。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?