Создание интерфейса для ObjectContext - PullRequest
6 голосов
/ 13 июля 2010

Я пытаюсь создать абстрагированный слой для ObjectContext. Я понимаю, что OC - это единица работы, но я не совсем понимаю, как написать хороший интерфейс для него. В идеале я хотел бы иметь возможность поменять мой 'RealDataContext', который реализует IDataContext, на что-то вроде 'FakeDataContext', который будет полностью в памяти.

Причина этого в том, что я хочу иметь возможность проверить свои репозитории на базе данных в памяти.

Спасибо!

1 Ответ

7 голосов
/ 13 июля 2010

Вы должны иметь возможность создать расширенный класс, который наследуется от ObjectContext и реализует интерфейс IDataContext.Чтобы действительно иметь возможность макетировать ObjectContext, ваш интерфейс IDataContext должен включать соответствующие сигнатуры (или свойства) для любого члена ObjectContext, который вы используете и хотите имитировать.Должно быть что-то вроде следующего:

interface IDataContext, IDisposable
{
    void AddObject(string entitySetName, object entity);
    void Attach(IEntityWithKey entity);
    void Detach(object entity);
    void DeleteObject(object entity);
    int SaveChanges();
    int SaveChanges(bool acceptChangesDuringSave);
    int SaveChanges(SaveOptions options);

    // Any other members you wish to be mockable
}

class DataContext: ObjectContext, IDataContext
{
    // nothing here
}

Технически говоря, поскольку DataContext наследует все от ObjectContect, реализация IDataContext позаботится об ObjectContext.Вам не нужно никакой дополнительной реализации в классе DataContext.До тех пор, пока вы всегда внедряете (или используете фабрику для создания) экземпляры IDataContext, а не ObjectContext, вы должны иметь возможность имитировать IDataContext при тестировании:

class SomeEntityRepository: IRepository<SomeEntity>
{
    public SomeEntityRepository(IDataContext context)
    {
        m_context = context;
    }

    private readonly IDataContext m_context;

    public SomeEntity GetById(long id)
    {
        // implementation
    }
}

// xUnit.NET & Moq
class SomeEntityRepositoryTests
{
    [Fact]
    public void GetById_returns_entity_when_valid_id_is_passed()
    {
        // state and context
        var mockContext = new Mock<IDataContext>();

        // arrangement
        mockContext.Setup(/* configure mock context here */);
        var repo = new SomeEntityRepository(mockContext.Object);

        // activity
        var entity = repo.GetById(100);

        // assertions
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...