我在第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
?我已经开始
[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);
}
关于c# - 使用Moq模拟自定义收藏,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39127120/