我有一个运行linq to sql查询的接口:
public interface IMyDataContext : IDisposable
{
ITable<MyTable> GetMyTable();
}在这个接口上,我运行了一个linq查询:
var results = from table1 in _MyDataContext.GetMyTable()
group table1 by table1.Column1 into myGroup
orderby myGroup.Count() descending
select new
{
Column1 = myGroup.Key,
Count = myGroup.Count()
};查询运行正常。我被困在编写单元测试的时候。如何让函数GetMyTable()返回一个带有一些假数据的模拟对象,请看下面的todo:
public class MockMyContextWrapper : IMyDataContext
{
public void Dispose()
{
}
public ITable<MyTable> GetMyTable()
{
var table = MockRepository.GenerateMock<ITable<MyTable>>();
//todo: code to return something so that the linq query fired on this table works
return table;
}
}发布于 2011-08-31 01:46:05
如果我正确理解了您的问题,您可能希望生成IMyDataContext的模拟,而不是只为测试而实现自己的实现。
在IMyDataContext模拟中,您可以像这样设置期望:
var dataContext = MockRepository.GenerateMock<IMyDataContext>();
var table = MockRepository.GenerateMock<ITable<MyTable>>();
dataContext.Expect(x => x.GetMyTable()).Return(table);您也可以在桌子模拟上设置期望。或者,您可以创建一个实现ITable接口的类的新实例,用内存中的测试数据填充这个实例。
发布于 2011-09-01 14:14:50
我不懂linq-to-sql,也不懂ITable。但当我看到这个界面时,我真的怀疑你是否应该模仿它。这太复杂了。模拟它可能会以编写整个数据库模拟器而告终,这显然没有意义。单元测试应该总是尽可能简单。
我建议使用实现ITable的真实类。明确地说:不要编写自己的实现。
发布于 2013-10-20 23:55:42
ITable包含3个不同的接口:IEnumerable、IQueryable和ITable中的其他东西。由于您所要做的就是查询表,因此您可以使用IQueryable,并将其传递给模拟存根:
IQueryable<MyTable> testTable = new[]{new MyTable{…}, new MyTable{…}, …, new MyTable{…}}.AsQueryable();
myMock.Stub(x => x.GetMyTable()).Return(testTable);每个new MyTable{…}将表示表中的一行。
如果/一旦您需要完整的ITable接口,例如,您想要添加或删除表中的行,您将想要创建自己的抽象类TestableTable,您可以扩展List (这样它已经实现了IEnumerable),并通过以下方式提供所有的IQueryable-methods:
public SomeType SomeMethodFromIQueryable(…)
{
return this.AsQueryable().SomeMthodFromIQueryable(…);
}现在只剩下ITable中的其他东西了。
var myMock = MockRepository.GenerateStub<TestableTable<MyTable>>(){ new MyTable{…}, …};
…
myMock.AssertWasCalled(x => x.Commit());希望这能有所帮助。
附言:我在为同样的问题寻找标准解决方案时遇到了你的问题。没有找到任何东西,所以我实现了这个。
https://stackoverflow.com/questions/7245121
复制相似问题