我对MOQ很新,有一个我无法解决的问题。我正在测试以下代码(我正在测试第一个 - ValidateInputBankFile ):
#region Constructor
private readonly IErrorRepository _errorRepository;
private readonly IFileSystem _fileSystem;
public IP_BankInfoDeserializer(IErrorRepository errorRepository, IFileSystem fileSystem)
{
_errorRepository = errorRepository;
_fileSystem = fileSystem;
}
#endregion
public IP_BankInfo ValidateInputBankFile(string sPath, App.BankType bankType)
{
if (!_fileSystem.FileExists((sPath)))
return null;
//first retrieve representative bank info
var tmpInfo = DeserializeBankInfo(bankType);
if (tmpInfo == null)
return null;//Does not exist
return tmpInfo;
}
public IP_BankInfo DeserializeBankInfo(App.BankType bankType)
{
if (!IsFileCorrect(bankType))
return null;
IP_BankInfo info = new IP_BankInfo();
using (var stream = new StreamReader(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + sFolder + Path.DirectorySeparatorChar +
bankType.ToString() + ".xml"))
{
XmlSerializer serializer = new XmlSerializer(typeof(IP_BankInfo));
try
{
info = serializer.Deserialize(stream) as IP_BankInfo;
}
catch (Exception ex)
{
info = null;
}
}
return info;
}
这是我的测试方法:
[TestMethod]
public void ValidateInputBank_ExistingPath_ExistingBank()
{
Mock<IFileSystem> fileSystem = new Mock<IFileSystem>();
fileSystem.Setup(n => n.FileExists(null)).Returns(true);
Mock<IP_BankInfoDeserializer> mocSerializer = new Mock<IP_BankInfoDeserializer>();
mocSerializer.Setup(n => n.DeserializeBankInfo(App.BankType.UniCredit)).Returns(new Models.IP_BankInfo());
var result = mocSerializer.Object.ValidateInputBankFile(null, App.BankType.UniCredit);
//Assert.AreEqual(serializer.Object.ValidateInputBankFile(null, App.BankType.UniCredit), new Models.IP_BankInfo());
}
我想要做的是避免调用 DeserializeBankInfo ,返回新的IP_BankInfo
,以便我可以在最后的断言阶段检查它。
问题是我的 var result 总是返回null。我不明白我做错了什么?
它也失败了以下代码mocSerializer.Setup(n => n.DeserializeBankInfo(App.BankType.UniCredit)).Returns(()=>null);
,但我传递了正确的参数。
答案 0 :(得分:2)
回答您的问题
问题是我的var结果总是返回null。我不明白我做错了什么?
ValidateInputBankFile
永远不会设置,你使用松散的模拟,因此它将返回null。
通过在模拟的构造函数中传递MockBehavior.Strict来使用严格模拟,并且会有一个异常,告诉您方法未设置。
应用一个安装程序,为ValidateInputBankFile
方法在该模拟上返回一个合适的值,它将表现正常。
提供建议
您正在测试中调用模拟对象上的方法:
var result = mocSerializer.Object.ValidateInputBankFile(null, App.BankType.UniCredit);
根据经验,您不应该在xxx.Object.MyMethod()
你不应该这样做的原因是因为你基本上只是把你的“安排”部分称为测试。
我觉得我需要问你这是通过这样做来实现的,因为你基本上只是测试你的测试。
答案 1 :(得分:0)
就我而言,看起来你正在尝试测试你的课程,但同时也要模拟它,以便不是所有课程都运行。 我认为这是不正确的,有效地您如何知道反序列化代码是否正常工作?
如果你的答案是另一个你在课堂上模拟其他功能的测试,我会回复说你需要将BankInfo
的反序列化功能抽象到另一个你可以模拟并将其注入的接口/类中你的IBankInfoValidator
。
这意味着您要从对象的反序列化中分离出验证,如果您的用例发生变化,这将有助于将来测试和可维护性/可扩展性。
就我个人而言,我刚刚废弃你的测试,开始寻找抽象出对象的反序列化,然后考虑将它作为单独的类进行测试。