0

我知道这个问题在这里被问了太多次,但我仍然无法弄清楚我的代码有什么问题。

我有一个实现单例的类。该类使用 Web 服务代理来访问数据。数据被缓存,随后的 2 次调用应导致对服务的一次调用。它确实有效,我可以在单步执行时看到它,但是测试失败。

[Test]
public void Test1()
{
    Mock<IAtomService> atomService = new Mock<IAtomService>();
    atomService.Setup(x => x.Get(It.IsAny<List<Identifier>>(), It.IsAny<AtomReturnFormat>()))
               .Returns<List<Identifier>, AtomReturnFormat>(
                   (list, format) => new AtomList { Atoms = new AtomCollection(list.Select(ident => new Atom { ID = Guid.Parse(ident.ID) })) });

    AtomCache.Instance.AtomService = atomService.Object;

    Guid id = Guid.NewGuid();
    List<string> ids = new List<string> { id.ToString() };

    AtomCache cache1 = AtomCache.Instance;
    cache1.Get(ids);

    AtomCache cache2 = AtomCache.Instance;
    cache2.Get(ids);

    AtomService.Verify(x => x.Get(It.IsAny<List<Identifier>>(), It.IsAny<AtomReturnFormat>()), Times.Once());
}

错误是

Expected invocation on the mock once, but was 0 times: x => x.Get(It.IsAny<List`1>(), It.IsAny<AtomReturnFormat>())

Configured setups:
x => x.Get(It.IsAny<List`1>(), It.IsAny<AtomReturnFormat>()), Times.Never
No invocations performed.

非常感谢任何帮助

更新

    public List<Atom> Get(List<string> atomIds)
    {
        if (atomIds == null)
            throw new ArgumentNullException("atomIds");

        Dictionary<string, Atom> cachedAtoms = Cache.Get(atomIds.Where(id => !string.IsNullOrEmpty(id)).Distinct().ToList());

        List<Atom> atoms = new List<Atom>();
        if (cachedAtoms != null)
        {
            List<string> missingAtomIds = atomIds.Except(cachedAtoms.Keys).ToList();
            atoms.AddRange(getMissingAtoms(missingAtomIds));

            atoms.AddRange(cachedAtoms.Where(kv => kv.Value != null).Select(kv => kv.Value));
        }
        return atoms;
    }

    private IEnumerable<Atom> getMissingAtoms(List<string> atomIds)
    {
        if (atomIds == null)
            throw new ArgumentNullException("atomIds");

        List<Atom> atoms = new List<Atom>();
        if (atomIds.Count > 0)
        {
            List<Atom> list = retrieveAtoms(atomIds);
            Cache.Add(list);
            atoms.AddRange(list);
        }

        return atoms;
    }

    private List<Atom> retrieveAtoms(List<string> atomIDs)
    {
        if (atomIDs == null)
            throw new ArgumentNullException("atomIDs");

        if (AtomService == null)
            throw new ApplicationException("AtomCache: Atom Service proxy is not initialized.");

        Guid temp;
        List<Identifier> idList = atomIDs.Where(id => !string.IsNullOrWhiteSpace(id) && Guid.TryParse(id, out temp))
                                         .Select(id => new Identifier {ID = id, Type = IdentifierTypeEnum.AtomPrimary})
                                         .ToList();

        List<Atom> atoms = atomIDs.Count == 0
                               ? new List<Atom>()
                               : ((AtomList) AtomService.Get(idList, AtomReturnFormat.Complete)).Atoms.ToList();

        return atoms;
    }
4

2 回答 2

0

除非我错过了您更新中的某些更改,否则我认为您就是问题所在。

在您的设置中,如果将标识符列表传递给模拟对象,则告诉模拟对象返回什么:

atomService.Setup(x => x.Get(It.IsAny<List<Identifier>>(), %<--snip--

但是,当您调用时,您将传递一个字符串列表:

List<string> ids = new List<string> { id.ToString() };

AtomCache cache1 = AtomCache.Instance;
cache1.Get(ids);

而且我在任何地方都看不到这个字符串列表被转换为标识符列表,所以模拟永远不会满足您的设置条件,即:当被要求提供任何标识符列表时,因此它正确报告它被问了 0 次.

于 2013-09-26T15:51:19.903 回答
0

我弄清楚了问题所在。这是我称之为“验证”的模拟的另一个实例。当我在这里复制代码时,我简化了代码并修复了错误:)

谢谢你

于 2013-09-26T17:39:06.950 回答