最小起订量 功能参数

Wil*_*llC 2 c# unit-testing moq func

我有一个使用 Func 参数的单元测试,我似乎无法使用最小起订量。查看 StackOverflow 上 Func 参数的其他示例,我认为这应该有效:

要测试的代码:

public class PatternManager : IPatternManager
{
    private readonly ICacheManager _cacheManager;
    private readonly IDataRepo _data;

    public PatternManager(ICacheManager cacheManager, IDataRepo dataRepo)
    {
        _cacheManager = cacheManager;
        _data = dataRepo;
    }

    public List<Pattern> GetAllPatterns()
    {
        var allPatterns = _cacheManager.Get(() => _data.GetAllPatterns(), nameof(_data.GetAllPatterns));

        return allPatterns;
    }

    public Pattern GetBestPattern(int[] ids)
    {
        var patternList = GetAllPatterns().Where(w => w.PatternId > 1);

        ... More code...
    }
    ...
}


public interface ICacheManager
{
    T Get<T>(Func<T> GetMethodIfNotCached, string cacheName = null, int? cacheDurationInSeconds = null, string cachePath = null);

}
Run Code Online (Sandbox Code Playgroud)

我得到的是 null,而不是我期望从 GetAllPatterns() 获得的模式列表。

[Test]
public void PatternManager_GetBestPattern()
{
    var cacheManager = new Mock<ICacheManager>();
    var dataRepo = new Mock<IDataRepo>();

    dataRepo.Setup(d => d.GetAllPatterns())
                    .Returns(GetPatternList());

    cacheManager.Setup(s => s.Get(It.IsAny<Func<List<Pattern>>>(), "", 100, "")) // Has optional params
                    .Returns(dataRepo.Object.GetAllPatterns());

    patternManager = new PatternManager(cacheManager.Object, dataRepo.Object);

    int[] pattern = { 1, 2, 3};

    var bestPattern = patternManager.GetBestPattern(pattern);

    Assert.AreEqual(1, bestPattern.PatternId);
}

private static List<Pattern> GetPatternList()
{ 
    ... returns a list of Pattern
}
Run Code Online (Sandbox Code Playgroud)

这个设置有什么问题吗?

Nko*_*osi 5

默认情况下,模拟返回null,因为设置与调用模拟成员时实际传递的内容不同。

查看被测成员中调用了什么

//...

var allPatterns = _cacheManager.Get(() => _data.GetAllPatterns(), nameof(_data.GetAllPatterns));

//...
Run Code Online (Sandbox Code Playgroud)

这很可能是 aFunc<List<Pattern>>和字符串"GetAllPatterns",其他可选参数默认为可选默认值。

现在看看测试中设置了什么

//...

cacheManager
    .Setup(s => s.Get(It.IsAny<Func<List<Pattern>>>(), "", 100, "")) // Has optional params
    .Returns(dataRepo.Object.GetAllPatterns());

//...
Run Code Online (Sandbox Code Playgroud)

空字符串和实际int值被设置为预期的值,但这并不是被测试成员实际调用的值。

因此,模拟不知道如何处理执行测试时传递的实际值,因此默认为null

重构设置以接受相应参数的任何值It.IsAny<>

//...

cacheManager
    .Setup(s => s.Get<List<Pattern>>(It.IsAny<Func<List<Pattern>>>(), It.IsAny<string>(), It.IsAny<int?>(), It.IsAny<string>()))
    .Returns((Func<List<Pattern>> f, string cn, int? cd, string cp) => f()); //Invokes function and returns result

//...
Run Code Online (Sandbox Code Playgroud)

并注意使用委托来捕获 中的参数Returns。这样,就可以像在被测成员中一样调用实际函数。