Rhino Mocks - 测试存储库层返回“对象引用未设置为实例”错误

时间:2011-11-14 13:15:29

标签: c# linq-to-sql rhino-mocks

我谨慎地说,我首先说我是Rhino Mocks的新手并且更普遍地嘲笑。

考虑到这一点,我正在尝试对我的Linq to SQL存储库层进行单元测试,以确保正在命中datacontext上的正确方法,并确保LINQ to SQL正确过滤。

〜为了清晰起见而已编辑〜

有问题的方法 - 'GetRecordWhere' - 在Repository类中定义。 它在DataContextWrapper上调用方法 - 'GetTable' - 这是我的Linq to SQL DataContext(自动生成)的自定义包装器,它被实现以使DataContext可以模拟。

public interface IDataContextWrapper : IDisposable
{
    IQueryable<TName> GetTable<TName>() where TName : class;
}

public class DataContextWrapper : IDataContextWrapper
{
    public IQueryable<TName> GetTable<TName>() where TName : class
    {
        return _db.GetTable<TName>().AsQueryable();
    }
}

public class Repository :  IRepository
{
    public T GetRecordWhere<T>(Expression<Func<T, bool>> predicate) where T : class
    {
        return _dataContext.GetTable<T>().Where(predicate).SingleOrDefault();
    }
}

当尝试存根'GetTable'方法以提供可查询的结果集时,我会抛出当前遇到的错误,该结果集可以使用'GetRecordWhere'方法进行查询。

ArgumentNullExcpetion:值不能为null。抛出参考线:

Arg<Expression<Func<Billing, bool>>>.Is.Anything

..我也尝试过Is.NotNull和一个特定的谓词。

单元测试示例:

    _dataContext = MockRepository.GenerateMock<IDataContextWrapper>();

    [Test]
    public void GetRecordWhere()
    {
        // Arrange
        var billing = new Billing { BillingId = 1 };
        var billingQueryList = new List<Billing> {billing};
        const int testId = 1;

       _dataContext.Stub(x => x.GetTable<Billing>()
                .Where(Arg<Expression<Func<Billing, bool>>>.Is.Anything)
                .SingleOrDefault())
                .Return(billing);

        _intRepository = new Repository(_dataContext);

        // Act
        var result = _intRepository.GetRecordWhere<Billing>(x => x.BillingId == testId);

        // Assert
        Assert.IsNotNull(result);
        Assert.AreEqual(result.BillingId, testId);
        _dataContext.AssertWasCalled(x => x.GetTable<Billing>());
    }

这对我对RhinoMocks的理解失败了吗?

非常感谢帮助!

1 个答案:

答案 0 :(得分:3)

任何想要使用Rhino.Mocks进行模拟的方法都需要是虚拟的,因此Rhino.Mocks可以拦截它并提供您定义的存根/模拟行为。看看你对GetTable的定义,它不是虚拟的,因此不能被嘲笑。

<强>更新

不要“链接”你的方法模拟。只需定义您希望方法执行的操作并返回值:

_dataContext.Stub(x => x.GetTable<Billing>()).Return(billingQueryList.AsQueryable());

我只是将您的示例代码插入到单元测试中,并使用上面的存根设置,测试通过。