我应该如何测试以下GetWorksheetPart
方法:
public class ExcelDocument : IExcelDocument
{
private readonly string _filePath;
public ExcelDocument(string filePath)
{
_filePath = filePath;
}
public WorksheetPart GetWorksheetPart(ISpreadsheetDocument excelDoc, string sheetName)
{
Sheet sheet = excelDoc.GetSheet(sheetName);
if (sheet == null)
{
throw new ArgumentException(
String.Format("No sheet named {0} found in spreadsheet {1}",
sheetName, _filePath), "sheetName");
}
return excelDoc.GetPartById(sheet.Id);
}
}
其中IExcelDocument
和包装器的SpreadsheetDocumentWrapper
接口为:
public interface IExcelDocument
{
WorksheetPart GetWorksheetPart(ISpreadsheetDocument excelDoc, string sheetName);
}
public interface ISpreadsheetDocument
{
Sheet GetSheet(string name);
WorksheetPart GetPartById(string id);
}
这是包装纸本身。
public class SpreadsheetDocumentWrapper : ISpreadsheetDocument
{
private SpreadsheetDocument excelDoc;
public SpreadsheetDocumentWrapper(SpreadsheetDocument excelDoc)
{
this.excelDoc = excelDoc;
}
public Sheet GetSheet(string sheetName)
{
return excelDoc.WorkbookPart.Workbook.Descendants<Sheet>()
.SingleOrDefault(s => s.Name == sheetName);
}
public WorksheetPart GetPartById(string id)
{
return (WorksheetPart)excelDoc.WorkbookPart.GetPartById(id);
}
}
最后,对GetWorksheetPart
进行了测试。问题是我不知道如何测试这个功能。我们的想法是在给定工作表名称和电子表格文档的情况下获得WorksheetPart
。
public class Test
{
[TestClass()]
public class ExcelUpdateLogicTests
{
[TestMethod()]
public void Excel_GetWorkseetPartTest()
{
Mock<ISpreadsheetDocument> mockSpreadhseet = new Mock<ISpreadsheetDocument>();
Sheet sheet = new Sheet();
string id = "1";
sheet.Name = "sheet";
sheet.Id = id;
mockSpreadhseet.Setup(doc => doc.GetSheet("sheet")).Returns(sheet);
mockSpreadhseet.Setup(doc => doc.GetPartById(id)).Returns(????);
Mock<IExcelDocument> mockExcelDocument = new Mock<IExcelDocument>();
WorksheetPart mockWorkseet = mockExcelDocument.Object
.GetWorksheetPart(mockSpreadhseet.Object, "sheet");
Assert.IsTrue(mockWorkseet.GetIdOfPart(mockWorkseet) == id);
}
}
}
以下是电子表格的通用OpenXML结构树:
Spreadsheet | WorkbookPart / | Workbook WorkbookStylesPart WorksheetPart | | | Sheets StyleSheet Worksheet | / (refers to SheetData Columns Worksheetparts) | Rows
由于ExcelDocument
是测试中的系统,因此无需模拟IExcelDocument
。您应该模拟/存根/伪造测试SUT 所需的依赖关系
现在我能让你的考试像这样通过。。。
public class Test {
[TestClass()]
public class ExcelUpdateLogicTests {
[TestMethod()]
public void Given_SheetName_ExcelDocument_Should_GetWorkseetPart() {
//Arrange
var stream = new MemoryStream();//Avoid having to use actual file on disk
var spreadsheetDocument = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook);
// Add a WorkbookPart.
WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
workbookpart.Workbook = new Workbook();
// Add a WorksheetPart.
WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
worksheetPart.Worksheet = new Worksheet(new SheetData());
// Add a sheets list.
Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
// Append the new worksheet and associate it with the workbook.
string expectedId = workbookpart.GetIdOfPart(worksheetPart);
string sheetName = "mySheet";
Sheet sheet = new Sheet() {
Id = expectedId,
SheetId = 1,
Name = sheetName
};
sheets.Append(sheet);
var wrapper = new SpreadsheetDocumentWrapper(spreadsheetDocument);
string fakeFilePath = "path";
var sut = new ExcelDocument(fakeFilePath);
//Act
WorksheetPart result = sut.GetWorksheetPart(wrapper, sheetName);
//Assert
Assert.IsNotNull(result);
var actualId = workbookpart.GetIdOfPart(result);
Assert.AreEqual(expectedId, actualId);
}
}
}
然而,这样做的过程对当前的设计提出了一些问题。
如果创建抽象的全部目的是隐藏实现细节,减少外部框架上的紧密耦合,使模拟和测试变得更容易,那么必须创建一个实际的SpreadsheetDocument
并将其包装用于测试似乎是多余的。
考虑到内部生成,框架的许多部分很难模拟。我会把这些隐藏在其他抽象后面,但鉴于我对这个系统的最终目标了解不够,我无法建议你应该采用什么设计结构。