Rhino Издевается — тестирующий уровень репозитория возвращает ошибку «ссылка на объект не установлена на экземпляр»

#c# #linq-to-sql #rhino-mocks

#c# #linq-to-sql #rhino-издевается

Вопрос:

Разумно, что я сначала говорю, что я новичок как в Rhino Mocks, так и в mocking в более общем плане.

Имея это в виду, я пытаюсь выполнить модульное тестирование моего уровня репозитория Linq to SQL, чтобы убедиться, что используются правильные методы в datacontext и что LINQ to SQL фильтрует правильно.

~ ОТРЕДАКТИРОВАНО для наглядности ~

Рассматриваемый метод — ‘GetRecordWhere’ — определен в классе репозитория. Он вызывает метод — ‘GetTable’ — в DataContextWrapper, который является моей пользовательской оболочкой для 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: не может быть нулевым. выдается ссылка на строку:

 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. Этот вопрос становится очень длинным, и теперь есть три обновления. В исходной части вашего вопроса упоминается получение исключения NullReferenceException. Позже вы упоминаете получение ArgumentNullException . Не могли бы вы повторно отредактировать свой вопрос и код, чтобы предоставить полный неудачный тестовый пример, содержащий только соответствующие части?

2. Обновлено основное сообщение с текущей проблемой и объяснением кода

Ответ №1:

Любой метод, который вы хотите издеваться с Rhino.Mocks должен быть виртуальным, поэтому Rhino.Mocks может перехватить ее и обеспечить заданное вами поведение с заглушкой / mocked. Глядя на ваше определение GetTable , оно не является виртуальным и, следовательно, не может быть подделано.

Обновить:

Не «цепляйте» свой метод издевается. Просто определите, что вы хотите, чтобы метод выполнял, и вернул значение:

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

Я только что подключил ваш пример кода к модульному тестированию, и с приведенной выше настройкой заглушки тест пройден.

Комментарии:

1. Не могли бы вы привести пример? Я также обновил свой вопрос с интерфейсом, который реализует содержащий класс, в котором определен GetTable<T>. Когда я издеваюсь над этим методом, я заглушаю метод, содержащийся в макете «datacontext».. если это имеет смысл…