我有一个 Transfer
类,简化后如下所示:
public class Transfer
{
public virtual IFileConnection source { get; set; }
public virtual IFileConnection destination { get; set; }
public virtual void GetFile(IFileConnection connection,
string remoteFilename, string localFilename)
{
connection.Get(remoteFilename, localFilename);
}
public virtual void PutFile(IFileConnection connection,
string localFilename, string remoteFilename)
{
connection.Get(remoteFilename, localFilename);
}
public virtual void TransferFiles(string sourceName, string destName)
{
source = internalConfig.GetFileConnection("source");
destination = internalConfig.GetFileConnection("destination");
var tempName = Path.GetTempFileName();
GetFile(source, sourceName, tempName);
PutFile(destination, tempName, destName);
}
}
IFileConnection
接口(interface)的简化版本如下所示:
public interface IFileConnection
{
void Get(string remoteFileName, string localFileName);
void Put(string localFileName, string remoteFileName);
}
真正的类应该处理 System.IO.IOException
当 IFileConnection
具体类失去与远程连接、发送电子邮件等时抛出的异常.
我想使用 Moq 创建一个 Transfer
类,并在所有属性和方法中将其用作我的具体 Transfer
类,除了 GetFile
方法被调用 - 然后我希望它抛出 System.IO.IOException
并确保 Transfer
类正确处理它。
我是否使用了正确的工具来完成工作?我这样做是对的吗?我将如何为 NUnit
编写该单元测试的设置?
最佳答案
这里是你如何模拟你的 FileConnection
Mock<IFileConnection> fileConnection = new Mock<IFileConnection>(
MockBehavior.Strict);
fileConnection.Setup(item => item.Get(It.IsAny<string>,It.IsAny<string>))
.Throws(new IOException());
然后实例化您的 Transfer 类并在您的方法调用中使用 mock
Transfer transfer = new Transfer();
transfer.GetFile(fileConnection.Object, someRemoteFilename, someLocalFileName);
更新:
首先,您必须只模拟您的依赖项,而不是您正在测试的类(在本例中为传输类)。在你的构造函数中声明这些依赖关系可以很容易地看到你的类需要哪些服务来工作。它还可以在您编写单元测试时用假货替换它们。目前不可能用假货替换这些属性。
由于您使用另一个依赖项设置这些属性,我会这样写:
public class Transfer
{
public Transfer(IInternalConfig internalConfig)
{
source = internalConfig.GetFileConnection("source");
destination = internalConfig.GetFileConnection("destination");
}
//you should consider making these private or protected fields
public virtual IFileConnection source { get; set; }
public virtual IFileConnection destination { get; set; }
public virtual void GetFile(IFileConnection connection,
string remoteFilename, string localFilename)
{
connection.Get(remoteFilename, localFilename);
}
public virtual void PutFile(IFileConnection connection,
string localFilename, string remoteFilename)
{
connection.Get(remoteFilename, localFilename);
}
public virtual void TransferFiles(string sourceName, string destName)
{
var tempName = Path.GetTempFileName();
GetFile(source, sourceName, tempName);
PutFile(destination, tempName, destName);
}
}
这样你就可以模拟 internalConfig 并让它返回 IFileConnection 模拟来做你想做的事。
关于c# - 模拟一个抛出异常(moq)的方法,但在其他方面表现得像被模拟的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10323794/