预期在 mock 上调用一次,但为 0 次 With Moq
Expected invocation on the mock once, but was 0 times With Moq
我遇到错误
Invocation on the mock once, but was 0 times
下面是我的代码结构
public class GenerateAddress : IGenerateAddress
{
public GenerateAddress(IAddress createAdd, IValidate validate) {
//constructor
}
public Address GetAddressFromA(string name){..}
}
public class SaveAddress : ISaveAddress
{
public SaveAddress(IGenerateAddress generateaddress) {
//constructor
}
public bool Save(string name)
{
var address = generateaddress.GetAddressFromA(name);
......
//Rest of the code to save
}
}
要测试的测试方法Class保存地址
public void TestVerifyGetAddressIsCalled()
{
var mockIAddress = new Mock<IAddress>();
var mockValidate = new Mock<IValidate>();
var genAddress = new Mock<IGenerateAddress>();
var objGenAdress = new GenerateAddress(mockIAddress.Object, mockValidate.Object) //
var objSaveAddress = new SaveAddress(objGenAdress);
objSaveAddress.Save("dddd");
//Verify if IGenerateAddress 'GenerateAddress' is called
genAddress.Verify(a=>a.GenerateAddress("ddddd"),Times.Once); // Throws Excepted Invocation
}
我需要验证是否调用了 GenerateAddress
。我也做了 Setup
并将值分配给 Address
对象,但即使这些值也没有设置..不知道出了什么问题。
看起来您是用 'dddd'(4 天)调用 Save
,但验证它是用 'ddddd'(5 天)调用的。
将真实数据放在变量中并在两种情况下都引用它更安全:
var name = "dddd";
objSaveAddress.Save(name);
genAddress.Verify(a=>a.GenerateAddress(name),Times.Once);
您正在使用手动创建的 IGenerateAddress
(objGenAdress
) 和 SaveAddress
而不是模拟的 genAddress
。
另外考虑到 SUT 是 SaveAddress
,它只需要 IGenerateAddress
,不需要其他模拟。
public void TestVerifyGetAddressIsCalled() {
//Arrange
var genAddress = new Mock<IGenerateAddress>();
var objSaveAddress = new SaveAddress(genAddress.Object);
var name = "dddd";
//Act
objSaveAddress.Save(name);
//Assert
//Verify if 'IGenerateAddress.GenerateAddress' is called
genAddress.Verify(a => a.GenerateAddress(name), Times.Once);
}
我认为在选择回复后,如果我们重构代码首先创建 SaveAddress class 作为模拟并传递参数 genAddress 并将 CallBase 属性 设置为 true。此 属性 的默认值为 false。如果你不使用这个参数你的方法调用 returns null 并且你得到 this.post title error.
var genAddress = new Mock<IGenerateAddress>();
var objSaveAddress = new Mock<SaveAddress>(genAddress.Object){CallBase = true};
var name = "dddd";
//Act
objSaveAddress.Object.Save(name);
//Assert
//Verify if IGenerateAddress 'GenerateAddress' is called
genAddress.Verify(a => a.GetAddressFromA(name), Times.Once);
我遇到错误
Invocation on the mock once, but was 0 times
下面是我的代码结构
public class GenerateAddress : IGenerateAddress
{
public GenerateAddress(IAddress createAdd, IValidate validate) {
//constructor
}
public Address GetAddressFromA(string name){..}
}
public class SaveAddress : ISaveAddress
{
public SaveAddress(IGenerateAddress generateaddress) {
//constructor
}
public bool Save(string name)
{
var address = generateaddress.GetAddressFromA(name);
......
//Rest of the code to save
}
}
要测试的测试方法Class保存地址
public void TestVerifyGetAddressIsCalled()
{
var mockIAddress = new Mock<IAddress>();
var mockValidate = new Mock<IValidate>();
var genAddress = new Mock<IGenerateAddress>();
var objGenAdress = new GenerateAddress(mockIAddress.Object, mockValidate.Object) //
var objSaveAddress = new SaveAddress(objGenAdress);
objSaveAddress.Save("dddd");
//Verify if IGenerateAddress 'GenerateAddress' is called
genAddress.Verify(a=>a.GenerateAddress("ddddd"),Times.Once); // Throws Excepted Invocation
}
我需要验证是否调用了 GenerateAddress
。我也做了 Setup
并将值分配给 Address
对象,但即使这些值也没有设置..不知道出了什么问题。
看起来您是用 'dddd'(4 天)调用 Save
,但验证它是用 'ddddd'(5 天)调用的。
将真实数据放在变量中并在两种情况下都引用它更安全:
var name = "dddd";
objSaveAddress.Save(name);
genAddress.Verify(a=>a.GenerateAddress(name),Times.Once);
您正在使用手动创建的 IGenerateAddress
(objGenAdress
) 和 SaveAddress
而不是模拟的 genAddress
。
另外考虑到 SUT 是 SaveAddress
,它只需要 IGenerateAddress
,不需要其他模拟。
public void TestVerifyGetAddressIsCalled() {
//Arrange
var genAddress = new Mock<IGenerateAddress>();
var objSaveAddress = new SaveAddress(genAddress.Object);
var name = "dddd";
//Act
objSaveAddress.Save(name);
//Assert
//Verify if 'IGenerateAddress.GenerateAddress' is called
genAddress.Verify(a => a.GenerateAddress(name), Times.Once);
}
我认为在选择回复后,如果我们重构代码首先创建 SaveAddress class 作为模拟并传递参数 genAddress 并将 CallBase 属性 设置为 true。此 属性 的默认值为 false。如果你不使用这个参数你的方法调用 returns null 并且你得到 this.post title error.
var genAddress = new Mock<IGenerateAddress>();
var objSaveAddress = new Mock<SaveAddress>(genAddress.Object){CallBase = true};
var name = "dddd";
//Act
objSaveAddress.Object.Save(name);
//Assert
//Verify if IGenerateAddress 'GenerateAddress' is called
genAddress.Verify(a => a.GetAddressFromA(name), Times.Once);