问题
Its prudent that I firstly say I'm new to both Rhino Mocks and to mocking more generally.
With that in mind i'm attempting to Unit test my Linq to SQL repository layer to ensure that the correct methods on the datacontext are being hit, and that the LINQ to SQL is filtering correctly.
~EDITED for clarity~
The method in question - 'GetRecordWhere' - is defined in the Repository class. It calls the method - 'GetTable' - on the DataContextWrapper which is my custom wrapper around the Linq to SQL DataContext (auto-generated) which was implemented to make the DataContext mockable.
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();
}
}
The error I am currently faced with is thrown when attempting to stub the 'GetTable' method to provide a queryable result set which can be queryed using the 'GetRecordWhere' method.
The ArgumentNullExcpetion: value cannot be null. is thrown with reference to the line:
Arg<Expression<Func<Billing, bool>>>.Is.Anything
.. which I have also tried with Is.NotNull and a specific predicate.
Unit test example:
_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>());
}
Is this a failing in my understanding of RhinoMocks?
Help is appreciated!
回答1:
Any method that you want to mock with Rhino.Mocks needs to be virtual so Rhino.Mocks can intercept it and provide the stubbed/mocked behavior you define. Looking at your definition of GetTable
, it is not virtual and therefore can't be mocked.
UPDATE:
Don't "chain" your method mocks. Just define what you want the method to do and return the value:
_dataContext.Stub(x => x.GetTable<Billing>()).Return(billingQueryList.AsQueryable());
I just plugged your sample code into a unit test and with the above stub setup, the test passes.
来源:https://stackoverflow.com/questions/8122145/rhino-mocks-testing-repository-layer-returns-object-reference-not-set-to-inst