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

Ste*_*her 4 c# unit-testing mstest moq

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

考虑以下:

    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;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,在存储库中,如果创建数据库成功,则返回 TRUE。如果所有 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

    }
Run Code Online (Sandbox Code Playgroud)

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

预期在模拟上至少调用一次,但从未执行过: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!!*
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*her 12

实际上,是 Chetan Ranpariya 在评论中提出了答案,我希望他会发布建议的答案而不是我,这样我就可以给他荣誉。

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

    repoMock.Verify(r => r.CreateDatabase(It.IsAny<string>()), Times.Once); 
    repoMock.Verify(r => r.UpdateCompanyTable(It.IsAny<Company>()), Times.Once);
Run Code Online (Sandbox Code Playgroud)

现在测试通过了。

谢谢车坦!

  • 无论我需要运行“Verify”,我总是复制\粘贴“Setup”行。然后只需将“设置”更改为“验证”即可。这样就不会发生冲突;) (2认同)