C# Moq-简单缓存测试

C# Moq-简单缓存测试,c#,unit-testing,mocking,moq,C#,Unit Testing,Mocking,Moq,我只是从Moq和单元测试开始。我在这里要做的是创建一个简单的测试,以确保缓存功能正常工作 为什么以下测试失败?测试失败,因为存储库被调用了两次。但是,我已经通过了调试器,并验证了第二个调用确实从缓存中提取,并且没有查询存储库 [TestMethod] public void Test_Cache() { var Service = new Service(_mockRepository.Object, _mockLogger.Object, _mockCacheStorage.Objec

我只是从Moq和单元测试开始。我在这里要做的是创建一个简单的测试,以确保缓存功能正常工作

为什么以下测试失败?测试失败,因为存储库被调用了两次。但是,我已经通过了调试器,并验证了第二个调用确实从缓存中提取,并且没有查询存储库

[TestMethod]
public void Test_Cache()
    {
var Service = new Service(_mockRepository.Object, _mockLogger.Object, _mockCacheStorage.Object);

Service.GetAll();
Service.GetAll();

_mockRepository.Verify(r => r.FindAll(), Times.Once());
}
更新

这是服务代码,我已经通过调试器验证了它的工作原理

public IList<Csa> GetAll()
    {
        try
        {
            string cacheKey = "GetAll";

            IList<Csa> activeList = _cacheStorage.Get<List<Csa>>(cacheKey);

            if (activeList == null)
            {
                activeList = _Repository.FindAll();
                _cacheStorage.Set(cacheKey, activeList);
            }

            return activeList;
        }
        catch (Exception exception)
        {
            _logger.Log(LogType.Error, exception.ToString());
            throw;
        }
    }

我认为你需要把你的测试分成两个独立的测试。一个测试应验证在activeList为null时访问存储库,另一个测试应验证在activeList不为null时跳过从存储库获取。关键是在跳过的版本中对_cacheStorage.Get调用进行“存根”

大概是这样的:

[TestMethod]
public void Test_Cache()
{
    var Service = new Service(_mockRepository.Object, _mockLogger.Object, _mockCacheStorage.Object);

    _mockCacheStorage.SetupGet(g => g.Get<List<Csa>>(It.IsAny<string>).Returns(new List<Csa>());

    Service.GetAll();

    _mockRepository.Verify(r => r.FindAll(), Times.Never());
}

我认为你需要把你的测试分成两个独立的测试。一个测试应验证在activeList为null时访问存储库,另一个测试应验证在activeList不为null时跳过从存储库获取。关键是在跳过的版本中对_cacheStorage.Get调用进行“存根”

大概是这样的:

[TestMethod]
public void Test_Cache()
{
    var Service = new Service(_mockRepository.Object, _mockLogger.Object, _mockCacheStorage.Object);

    _mockCacheStorage.SetupGet(g => g.Get<List<Csa>>(It.IsAny<string>).Returns(new List<Csa>());

    Service.GetAll();

    _mockRepository.Verify(r => r.FindAll(), Times.Never());
}

您的模拟缓存存储总是返回null,这似乎是一个问题。您正在模拟缓存存储,因此我猜对缓存存储进行Get和Set的调用没有正确地从列表中保存。您有几个选择:

在模拟缓存存储上进行模拟获取和设置,以获取和设置局部变量或命令 创建缓存存储接口的存根实现,该实现只在下面使用字典 不要为缓存存储注入依赖项,只需在实现中使用字典即可。
您的模拟缓存存储总是返回null,这似乎是一个问题。您正在模拟缓存存储,因此我猜对缓存存储进行Get和Set的调用没有正确地从列表中保存。您有几个选择:

在模拟缓存存储上进行模拟获取和设置,以获取和设置局部变量或命令 创建缓存存储接口的存根实现,该实现只在下面使用字典 不要为缓存存储注入依赖项,只需在实现中使用字典即可。
你能展示一下你的服务代码吗?@CRice我更新了我原来的帖子。你似乎把一切都搞糟了。你在测试什么?@Mitch-Wheat-我试图测试当服务方法被调用两次时,对存储库的调用只执行一次。第二个调用应该从缓存中检索,而不是从存储库中检索,我已经通过调试器验证了它的工作原理,我正在试着了解模拟和单元测试。@Beavis-这是你编写的第一个涉及此方法的测试吗?你能展示你的服务代码吗?@CRice我更新了我原来的帖子。你似乎已经模拟了所有内容。你在测试什么?@Mitch-Wheat-我试图测试当服务方法被调用两次时,对存储库的调用只执行一次。第二个调用应该从缓存中检索,而不是从存储库中检索,我已经通过调试器验证了它的有效性,但是,我正在尝试了解模拟和单元测试。@Beavis-这是您编写的第一个涉及此方法的测试吗?