我遇到了使用EPPlus的单元测试类问题。在我看来,我有两个选择。
我可以嘲笑&将HttpPostedFileBase注入方法,或者我可以模拟&注入EPPlus ExcelPackage类。
模拟HttpPostedFileBase,至少做一个真正的模拟,似乎有限。我可以模拟文件的基本属性(MIME类型,文件名等),但是以允许测试实际与之交互的方式模拟其InputStream似乎非常困难。我能想到的唯一解决方案是提供一个真正的excel文件,用它创建一个真正的FileStream,并将该FileStream分配给我的模拟HttpPostedFileBase的InputStream。但它在技术上是一种集成测试,而不是单元测试。
const string FakeFileName = "TestExcelFile.xlsx"; // path to an actual excel file
var fileStream = new FileStream(FilePath, FileMode.Open);
var fakeFile = A.Fake<HttpPostedFileBase>();
A.CallTo(() => fakeFile.InputStream).Returns(fileStream);
我想如果我想进行实际的单元测试,我可以模拟并注入EPPlus ExcelPackage类。然后我可以模拟相关的工作表,列和&amp;单元类,动态设置其属性以适应我的测试条件,而从不接触真实文件。问题是,大多数EPPlus类都是密封的,所以我不能用FakeItEasy来模拟它们。我尝试为它们创建包装类(见下文),所以我可以模拟包装类而不是......但是我需要模拟/包装的一些类有内部构造函数,所以我不能实例化它们。 (我尝试使用一些丑陋的黑客来解决内部构造函数问题,但没有成功。)所以我用这个选项碰到了墙。
我还是一个新手,还有很多需要学习的东西。也许我的包装类概念是不正确的,我做错了。有没有办法绕过这个我无法看到,或者我应该放弃,使用一个真正的excel文件,并称之为集成测试?到目前为止,这是我倾向于的。
public class ExcelWorksheetsWrapper : IEnumerable<ExcelWorksheet>
{
public readonly ExcelWorksheets _excelWorksheets;
public ExcelWorksheetsWrapper()
{
// internal constructor, can't instantiate
_excelWorksheets = new ExcelWorksheets();
}
public ExcelWorksheet Add(string worksheetName)
{
return _excelWorksheets.Add(worksheetName);
}
public IEnumerator<ExcelWorksheet> GetEnumerator()
{
return _excelWorksheets.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return _excelWorksheets.GetEnumerator();
}
}
答案 0 :(得分:2)
嘲弄第三方图书馆往往是一个痛苦的问题,并创造了神秘的单元测试。
每个测试应该简短,易于阅读和理解。应该很容易看到测试,以了解预期的成功操作应该是什么。
通常最好围绕第三方库创建包装类,并在这些类上使用接口。然后,您可以创建实现这些接口的模拟对象,仅用于测试。
然而,这说起来容易做起来难。显然,第三方库所做的事情不仅仅是切断代码并进行有意义的测试。
在这些情况下,您仍然应该使用自己的接口,但将这些类型的单元测试隔离到最小的依赖于第三方库的对。
尝试看一下SOLID编程模式。使用该模式构建的系统通常更容易测试,因为一切都松散耦合。