[英]Unit testing classes that use EPPlus
我在使用 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 类。 然后我可以模拟相关的工作表、列和单元格类,动态设置它们的属性以适应我的测试条件,同时从不接触真实文件。 问题是,大多数 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();
}
}
模拟第三方库通常是一件令人头疼的事情,并且会创建神秘的单元测试。
每个测试都应该简短,易于阅读和理解。 查看测试应该很容易理解预期的成功操作应该是什么。
通常最好围绕第三方库创建包装类,并在这些类上使用接口。 然后,您可以创建实现这些接口的模拟对象,仅用于测试。
尽管如此,说起来容易做起来难。 显然,第三方库会做一些事情,这些事情不能只是剪掉代码并进行有意义的测试。
在这些情况下,您仍然应该使用自己的接口,但将这些类型的单元测试隔离到依赖第三方库的最低限度。
尝试查看 SOLID 编程模式。 使用该模式构建的系统通常更容易测试,因为一切都是松散耦合的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.