[英]Mock a Custom Collection using Moq
我在第3方库中有以下类型
public interface IWorkbook : IPrintable
{
...
IWorksheets Worksheets { get; }
}
工作表界面是
public interface IWorksheets : IEnumerable
{
IWorksheet this[int index] { get; }
IWorksheet this[string name] { get; }
IWorkbookSet WorkbookSet { get; }
IWorksheet Add();
IWorksheet AddAfter(ISheet sheet);
IWorksheet AddBefore(ISheet sheet);
bool Contains(IWorksheet worksheet);
}
我有一个要进行单元测试的方法,该方法采用IWorkbook
并遍历包含的工作表。 我的问题是如何使用Moq为IWorksheets
创建模拟集合。 IWorksheet
界面是
public IWorksheet
{
...
public Name { get; set; } // This is the only property I am interested in.
}
所以,我怎么能生成一个假IWorkbook
其中有一个假的集合( IWorksheets
的) IWorksheet
S'
我已经开始
[TestInitialize]
public void Initialize()
{
List<string> fakeSheetNames = new List<string>()
{
"Master",
"A",
"B",
"C",
"__ParentA",
"D",
"wsgParentB",
"E",
"F",
"__ParentC",
"__ParentD",
"G"
};
List<IMock<IWorksheet>> sheetMockList = new List<IMock<IWorksheet>>();
foreach (string name in fakeSheetNames)
{
Mock<IWorksheet> tmpMock = new Mock<IWorksheet>();
tmpMock.Setup(p => p.Name).Returns(name);
sheetMockList.Add(tmpMock);
}
var mockWorksheets = new Mock<IWorksheets>();
mockWorksheets.Setup(p => p).Returns(sheetMockList);
...
}
但是我不能这样做(显然)
无法从“ System.Collections.Generic.List>”转换为“ SpreadsheetGear.IWorksheets”
如何模拟IWorksheets
集合?
所以我现在有以下代码按照下面的答案创建我的模拟
[TestClass]
public class WorkbookStrucutreProviderTests
{
private Mock<IWorkbookSet> mockWorkbookSet;
private readonly List<string> parentPrefixes = new List<string>() { "__", "wsg" };
[TestInitialize]
public void Initialize()
{
List<string> fakeSheetNames = new List<string>()
{
"Master",
"A",
"B",
"C",
"__ParentA",
"D",
"wsgParentB",
"E",
"F",
"__ParentC",
"__ParentD",
"G"
};
List<IWorksheet> worksheetMockList = new List<IWorksheet>();
foreach (string name in fakeSheetNames)
{
Mock<IWorksheet> tmpMock = new Mock<IWorksheet>();
tmpMock.Setup(p => p.Name).Returns(name);
tmpMock.Setup(p => p.Visible)
.Returns(parentPrefixes.Any(p => name.StartsWith(p)) ?
SheetVisibility.Hidden :
SheetVisibility.Visible);
worksheetMockList.Add(tmpMock.Object);
}
List<IWorkbook> workbookMockList = new List<IWorkbook>();
Mock<IWorkbook> mockWorkbook = new Mock<IWorkbook>();
mockWorkbook
.Setup(p => p.Worksheets.GetEnumerator())
.Returns(worksheetMockList.GetEnumerator());
workbookMockList.Add(mockWorkbook.Object);
mockWorkbookSet = new Mock<IWorkbookSet>();
mockWorkbookSet
.Setup(p => p.Workbooks.GetEnumerator())
.Returns(workbookMockList.GetEnumerator());
}
[TestMethod]
public async Task StrucutreGenerationAsyncTest()
{
WorkbookStructureProvider provider = new WorkbookStructureProvider();
await provider.GenerateWorkbookStructureAsync(mockWorkbookSet.Object);
foreach (var item in provider.Structure)
{
Trace.WriteLine("--" + item.Name);
if (item.HasChildren)
{
foreach (var child in item.Children)
{
Trace.WriteLine("-- --" + child.Name);
}
}
}
}
但是在GenerateWorkbookStructureAsync()
方法中,我有这段代码
bool IsUserCostWorkbook = false;
if (workbook.Worksheets.Cast<IWorksheet>().Any(
ws => ws.Name.CompareNoCase(Keywords.Master)))
{
// TODO Extra check for UserCost template.
IsUserCostWorkbook = true;
}
这里的workbook.Worksheets
集合为空。 我以为我的模拟GetEnumerator
可以解决这个问题; 没有。
那么,如何模拟IWorksheets
以便可以执行以下操作?
foreach (var ws in workbook.Worksheets.Cast<IWorksheet>())
{
...
}
以下示例在测试时通过
[TestMethod]
public void Mock_Custom_Collection_Using_Moq() {
//Arrange
var parentPrefixes = new List<string>() { "__", "wsg" };
var fakeSheetNames = new List<string>(){
"Master",
"A",
"B",
"C",
"__ParentA",
"D",
"wsgParentB",
"E",
"F",
"__ParentC",
"__ParentD",
"G"
};
var worksheetMockList = new List<IWorksheet>();
foreach (string name in fakeSheetNames) {
var worksheet = Mock.Of<IWorksheet>();
worksheet.Name = name;
worksheet.Visible = parentPrefixes.Any(p => name.StartsWith(p)) ?
SheetVisibility.Hidden :
SheetVisibility.Visible;
worksheetMockList.Add(worksheet);
}
var mockWorkbook = new Mock<IWorkbook>();
mockWorkbook
.Setup(p => p.Worksheets.GetEnumerator())
.Returns(() => worksheetMockList.GetEnumerator());
var workbook = mockWorkbook.Object;
//Act
bool IsUserCostWorkbook = false;
if (workbook.Worksheets.Cast<IWorksheet>()
.Any(ws => ws.Name.Equals("Master", StringComparison.InvariantCultureIgnoreCase))) {
IsUserCostWorkbook = true;
}
//Assert
Assert.IsTrue(IsUserCostWorkbook);
}
对不起,伪代码:
var fakeWorksheet = new Mock<IWorksheet>();
//You can use AutoFixture here to auto-populate properties or you can set only required props
fakeWorksheet.Setup(p => p.Name).Returns("TestName");
var worksheetsMock = new Mock<IWorksheets>()
//here mock some members that you need
worksheetsMock.Setup(w => w.Add()).Returns(fakeWorksheet.Object);
var workbookMock = new Mock<IWorkbook>();
workbookMock.Setup(w => w.Worksheets).Returns(worksheetsMock.Object);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.