Moq 验证失败异常:预期至少对模拟调用一次,但从未执行过

Moq failed exception on Verify: Expected invocation on the mock at least once, but was never performed

这是另一个菜鸟菜鸟问题:

考虑以下几点:

    public class Company
{
    public string CompanyName {get; set; }
    public string Address {get; set; }
}

public interface IRepository
{
    bool CreateDatabase(string name);
    bool UpdateTable(Company _co);
}

public class MyService
{
    private IRepository _repo;

    public MyService(IRepository repo)
    {
        _repo = repo;
    }

    public bool Commit(string database_name, Company co)
    {
        if (_repo.CreateDatabase(database_name))
            return _repo.Commit(co);

        return false;
    }
}

所以在存储库中,如果创建数据库成功,那么它 returns 正确。如果所有 SQL UPDATE 也成功,则 UpdateTable 也是如此。然后我所做的就是将结果传递回 ViewModel 以表明一切顺利。

所以在我的 MSTest 中:

    [TestMethod]
    public void Test_If_Calls_CreateDatabase_And_UpdateTable()
    {
        var name = "test";
        var repoMock = new Mock<IRepository>();
        var _company = new Company();
        repoMock.Setup(r => r.CreateDatabase(It.IsAny<string>())).Returns(true);
        repoMock.Setup(r => r.UpdateCompanyTable(It.IsAny<Company>())).Returns(true);

        var engine = new MyService(repoMock.Object);

        var result = engine.Commit(name, _company);

        Assert.IsTrue(result);   // PASSES
        repoMock.Verify(r => r.CreateDatabase(name), Times.Once);           //FAILS
        repoMock.Verify(r => r.UpdateCompanyTable(_company), Times.Once);   //FAILS

    }

这就是事情变得如此糟糕的地方。结果 returns 返回 true,这意味着它得到了正确的结果,但是 Moq 验证失败,我得到这个异常:

Expected invocation on the mock at least once, but was never performed: r => r.CreateDatabase("test")

这是为什么?即使我删除 Times.Once 并且只有 repoMock.Verify(r => CreateDatabase(name)),我仍然会收到相同的失败错误消息。

有什么建议吗?

更正

代码确实是第一个建议的答案。但是出现了一些复制和粘贴错误,这是因为我正在尝试一些变体以使单元测试正常工作。例如,我尝试了这些变体:

engine.Commit(name, _company); // tried that first, that failed
engine.Commit(It.IsAny<string>(), It.IsAny<Company>()); // failed too
engine.Commit(new String(), new Company()); // fails as well
engine.Commit(null, _company)); // fails!! GRR!!
engine.Commit(null, null)); // FAIL! *cocks gun* IT'S HAMMER TIME! *BANG!!*

我原以为第一行会像某人建议的那样工作,但事实并非如此,因此我在这里寻求帮助。

实际上,是 Chetan Ranpariya 在评论中提出了答案,我希望他能代替我发布建议的答案,这样我就可以归功于他。

因为我使用的是 It.IsAny<string>()It.IsAny<Company>(),所以在尝试验证这些方法确实是 运行 一次时,我需要具有相同的签名。因此,要测试它,应该是这样的:

    repoMock.Verify(r => r.CreateDatabase(It.IsAny<string>()), Times.Once); 
    repoMock.Verify(r => r.UpdateCompanyTable(It.IsAny<Company>()), Times.Once);

现在测试通过了。

谢谢车坦!