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);
现在测试通过了。
谢谢车坦!
这是另一个菜鸟菜鸟问题:
考虑以下几点:
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);
现在测试通过了。
谢谢车坦!