C# 这是嘲笑还是存根?
我有下面的方法要测试,我已经编写了两个测试,测试抛出异常的场景,我想知道哪个是正确的C# 这是嘲笑还是存根?,c#,unit-testing,c#-4.0,dependency-injection,moq,C#,Unit Testing,C# 4.0,Dependency Injection,Moq,我有下面的方法要测试,我已经编写了两个测试,测试抛出异常的场景,我想知道哪个是正确的 namespace JimBob.CsvImporter.Entity { public interface IIOManager { Stream OpenFile(string path); TextReader ReturnReader(string path); } public class IOManager : IIOManag
namespace JimBob.CsvImporter.Entity
{
public interface IIOManager
{
Stream OpenFile(string path);
TextReader ReturnReader(string path);
}
public class IOManager : IIOManager
{
public Stream OpenFile(string path)
{
return File.Open(path, FileMode.Open);
}
public TextReader ReturnReader(string filePath)
{
return new StreamReader(filePath);
}
}
public class EntityVerification
{
private IIOManager _iomgr;
public EntityVerification(IIOManager ioManager)
{
this._iomgr = ioManager;
}
...
/// <summary>
/// Ensures user can open file.
/// </summary>
/// <param name="errorMessageList">A running list of all errors encountered.</param>
public void ValidateAccessToFile(string filePath, List<string> errorMessageList)
{
try
{
using (FileStream fs = (FileStream)_iomgr.OpenFile(filePath))
{
if (fs.CanRead && fs.CanWrite) { }
else
{
errorMessageList.Add("Can not read/write to the specified file.");
}
}
}
catch (Exception e)
{
errorMessageList.Add(e.Message);
}
}
名称空间JimBob.CsvImporter.Entity
{
公共接口管理器
{
流OpenFile(字符串路径);
TextReader ReturnReader(字符串路径);
}
公共类IOManager:IIOManager
{
公共流OpenFile(字符串路径)
{
返回File.Open(路径,FileMode.Open);
}
公共文本读取器ReturnReader(字符串文件路径)
{
返回新的StreamReader(文件路径);
}
}
公共类实体验证
{
私人管理人(iomgr);
公共实体验证(IIOManager ioManager)
{
这个。_iomgr=ioManager;
}
...
///
///确保用户可以打开文件。
///
///遇到的所有错误的运行列表。
public void ValidateAccessToFile(字符串文件路径,列表错误消息列表)
{
尝试
{
使用(FileStream fs=(FileStream)\u iomgr.OpenFile(filePath))
{
如果(fs.CanRead&&fs.CanWrite){}
其他的
{
errorMessageList.Add(“无法读取/写入指定文件”);
}
}
}
捕获(例外e)
{
errorMessageList.Add(e.Message);
}
}
测试:
[Test]
public void ValidateAccessToFile_CanReadWriteToFile_ThrowException()
{
List<String> errorMessageList = new List<string>();
StubService stub = new StubService();
EntityVerification testObject = new EntityVerification(stub);
testObject.ValidateAccessToFile("ergesrg", errorMessageList);
Assert.AreEqual(errorMessageList.Count, 0);
}
[Test]
public void ValidateAccessToFile_CanReadWriteToFile_ThrowsException()
{
Mock<IIOManager> mock = new Mock<IIOManager>();
mock.Setup(x => x.ReturnReader(It.IsAny<string>())).Throws(new InvalidOperation("throw baby."));
EntityVerification testObject = new EntityVerification(mock.Object);
List<String> errorMessageList = new List<string>();
testObject.ValidateAccessToFile("blabla.txt", errorMessageList);
Assert.AreEqual(errorMessageList.Count, 0);
}
public class StubService : IIOManager
{
public Exception ex;
public Stream OpenFile(String path)
{
throw ex;
}
}
[测试]
public void ValidateAccessToFile\可以通过异常()读写文件
{
List errorMessageList=新建列表();
StubService stub=新StubService();
EntityVerificationTestObject=新的EntityVerification(存根);
ValidateAccessToFile(“ergesrg”,errorMessageList);
Assert.AreEqual(errorMessageList.Count,0);
}
[测试]
public void ValidateAccessToFile\可以通过异常()读写文件
{
Mock Mock=新Mock();
mock.Setup(x=>x.ReturnReader(It.IsAny()).Throws(新的无效操作(“throw baby”));
EntityVerificationTestObject=新的EntityVerification(mock.Object);
List errorMessageList=新建列表();
ValidateAccessToFile(“blabla.txt”,errorMessageList);
Assert.AreEqual(errorMessageList.Count,0);
}
公共类StubService:IIOManager
{
公共例外;
公共流OpenFile(字符串路径)
{
掷骰子;
}
}
这两个测试都只是检查一个局部变量,在本例中是errorMessageList,它包含一些东西,所以我不确定应该使用哪个
如有任何意见,将不胜感激
首先谢谢你,你不应该检查一下你是否在列表中添加了错误信息吗
Assert.AreEqual(errorMessageList.Count, 1);
第二,尽管第二个类不那么冗长,而且可读性更好(因为您不需要实现另一个类),这没关系-这两个测试都是实现同一目标的有效方法。只需选择一个,然后继续下一个功能…第二个测试看起来更好。我认为您可以使用
IIOManager
使用其他方法。您应该维护第一个测试(更新存根),但对第二个测试不做任何操作
关于
IOManager
,FileSystem
-看起来更合适的类名“我认为IIOManager还有其他方法,您应该维护第一个测试(更新存根),但对第二个测试不做任何操作。”对不起,我不明白。你能详细说明一下吗。IIOManager-is接口,所以你的存根取决于接口。在IIOManager中进行任何更改后,你必须更新存根(例如添加另一个方法)。Mock(第二次测试)不依赖于接口实现。因此,第二个测试比第1个测试更容易维护。我不确定为什么我不应该检查它是否添加了消息。我没有重新引发异常,所以我需要检查它是否向errorMessageList添加了一些内容,以便我可以确定是否可以继续程序的下一阶段。是的,so检查列表是否包含一条消息,而不是零…或使用Assert.that(errorMessageList,Is.not.Empty);
@SilverNinja,感谢您的编辑。