Поддельный DataRepository - эмуляция базы данных - PullRequest
1 голос
/ 13 октября 2011

Краткая информация: я использую C # 4.0 и RhinoMocks (с AAA)

Я объясню с помощью некоторого кода, что я думаю сделать:

public class SampleData
{
    private List<Person> _persons = new List<Person>()
    {
         new Person { PersonID = 1, Name = "Jack"},
         new Person { PersonID = 2, Name = "John"}
    };

    public List<Person> Persons
    {
        get { return _persons; }
    }
}

Так что это класс, который имитирует данные в БД. Теперь я хочу использовать эти данные в своих модульных тестах. Другими словами, вместо того, чтобы извлекать данные из БД, я хочу вывести их из хранилища данных.

Я думаю, что смогу добиться этого, заглушив Репозиторий и заставив его использовать вместо этого Репозиторий:

UC1003_ConsultantsBeherenBL consultantsBeherenBL = new UC1003_ConsultantsBeherenBL();

consultantsBeherenBL = MockRepository.GeneratePartialMock<UC1003_ConsultantsBeherenBL>();
consultantsBeherenBL.Repository = MockRepository.GenerateMock<IRepository>();

Это заставило бы мой код автоматически искать данные в DataRepository. Таким образом, вместо того, чтобы заглушить метод и напрямую вставить список (например, d => d.Find (Arg.Is.Anything)). IgnoreArguments (). Return (список, который вы только что заполнили)) я получил бы «настоящий» возврат данных (данные, отфильтрованные из хранилища данных). Это означает, что я могу проверить, действительно ли мой код может что-то найти, без необходимости вставлять тестовые данные в мою БД (интеграционный тест).

Как бы я реализовал такую ​​вещь? Я пытался искать в Интернете статьи или вопросы, но я не могу найти много: /

Любая помощь приветствуется.

РЕДАКТИРОВАТЬ: Я пытался SimpleInjector и StructureMap, но я застрял реализации одного из них.

В настоящее время я использую репозиторий в своей платформе сущностей, поэтому мой baseBL выглядит следующим образом (примечание: все мои другие BL наследуются от этого):

public class BaseBL
{
    private IRepository _repository;

    public IRepository Repository
    {
        get
        {
            if (_repository == null)
                _repository = new Repository(new DetacheringenEntities());
            return _repository;
        }
        set { _repository = value; }
    }

    public IEnumerable<T> GetAll<T>()
    {
    ... --> Generic methods

Мой класс репозитория:

public class Repository : BaseRepository, IRepository
{
    #region Base Implementation

    private bool _disposed;

    public Repository(DetacheringenEntities context)
    {
        this._context = context;
        this._contextReused = true;
    }

    #endregion

    #region IRepository Members

    public int Add<T>(T entity)
    ... --> implementations of generic methods

Насколько я могу судить, теперь я должен иметь возможность сказать в своих тестах, что вместо использования DetacheringenEntities мне нужно использовать мой DataRepository. Я не понимаю, как я переключаю свою платформу сущностей с классом данных, потому что этот класс данных туда не вписывается.

Должен ли я позволить моему DataRepository наследовать мой класс IRepository и создавать свои собственные реализации?

public class SampleData : IRepository

Но я не могу делать такие вещи со своими списками: /

    public IEnumerable<T> GetAll<T>()
    {
        return Repository.GetAll<T>();
    }

Большое спасибо еще раз за помощь

РЕДАКТИРОВАТЬ: Я понял, что для модульного теста не требуется хранилище данных, поэтому я просто проверяю эту логику в интеграционном тесте. Это делает хранилище данных бесполезным, поскольку код может быть протестирован без хранилища. Я хотел бы поблагодарить всех за помощь, спасибо:)

1 Ответ

4 голосов
/ 13 октября 2011

Используйте инфраструктуру внедрения зависимостей для обработки ваших зависимостей.В своем модульном тесте вы можете заменить реальную реализацию на заглушку.

Например, в StructureMap вы скажете это в своем коде.«Хорошо, теперь дайте мне активный экземпляр IDataRepository», для вашего обычного кода это будет указывать на реализацию в реальной базе данных.В вашем юнит-тесте вы можете переписать это, поставив ObjectFactory.Inject(new FakeDataRepository()).Поддельное репо затем используется всем вашим кодом, что позволяет очень легко протестировать одну единицу работы. Í

...