Я работаю над написанием некоторых модульных тестов с Rhino Mocks для приложения WPF, написанного на C#, который использует Unity для инъекции зависимостей и использует MVVM-айтиктура. Я не очень разбираюсь в модульном тестировании с Rhino Mocks, поэтому я не уверен, какие лучшие практики еще нет.Rhino Mocks - ожидать/заглушить не виртуальный метод из внешней зависимости
В модели представления я собираюсь писать модульные тесты, есть класс ввода данных с зависимостями, мы будем называть его DataAccess, то есть из внешней сборки, которую я не контролирую. Только один экземпляр зарегистрирован в контейнере Unity, потому что DataAccess имеет кэш, и желательно разделить этот экземпляр по всему приложению через контейнер Unity, чтобы повысить производительность. Теперь мне нужно издеваться над DataAccess в моем модульном тесте, потому что я не контролирую данные в базе данных. Я хочу заглушить или ожидать, что метод Retrieve вернет определенное значение, но DataAccess не реализует интерфейс, а метод, который мне нужен для заглушки, не является виртуальным. Из того, что я читал онлайн, Rhino Mocks не может переопределить не виртуальный метод, и единственным другим вариантом является издевательствование интерфейса с методами, которые вы хотите переопределить. Ни один из этих параметров не подходит для этого случая, потому что у меня нет кода DataAccess. Я слышал, что TypeMock имеет возможность переопределять не виртуальные методы, но убедить мою компанию переключиться на платную насмешливую библиотеку, вероятно, не произойдет, поэтому я застрял с Rhino Mocks. Так есть способ издеваться над этим классом и переопределить этот метод Rhino Mocks?
public class DataAccess //in an external assembly
{
public TEntity Retrieve(TKey key);
}
public class ViewModel //in the client project
{
[Dependency]
public DataAccess DataAccess { get; set; }
}
я придумал возможное решение, но он не использует издевается, и я хотел бы использовать издевается, потому что есть много мест, где мы имеем такую ситуацию. Моя идея - создать класс-оболочку (поддельный) для DataAccess, который имеет те же методы и свойства, что и DataAccess, за исключением того, что все важные методы/свойства отмечены как виртуальные, и я положу этот класс в свой тестовый проект. Затем в инициализаторе модульного теста я зарегистрирую сопоставление типов из DataAccess в класс оболочки в контейнере Unity, чтобы виртуальная машина, созданная в моем модульном тесте, вместо этого получала экземпляр класса-оболочки. Вы видите какие-то недостатки в этом направлении, кроме создания кучи классов-оболочек?
public class DataAccessFake : DataAccess //in the test project
{
public new virtual TEntity Retrieve(TKey key) //hides the DataAccess Retrieve with a virtual one
{
return base.Retrieve(key);
}
}
Действительно ли это работает? Объекты, которые зависят от DataAccess, по-прежнему будут вызывать DataAccess.Retrieve, а не DataAccessFake.Retrieve, которые являются двумя совершенно разными способами. –
Ключевое слово 'new' указывает, что метод скрывает свой унаследованный элемент. Так что да, он должен назвать поддельный метод. – StarChar
Вы проверили это? –