为ObjectContext创建接口

The*_*Sky 6 c# entity-framework

我正在尝试为其创建一个抽象层ObjectContext.我理解OC是一个工作单元,但我并不完全是如何为它编写一个好的界面.理想情况下,我希望能够换掉我的'RealDataContext',它实现IDataContext了像'FakeDataContext'这样完全在内存中的东西.

原因是我希望能够针对内存数据库测试我的存储库.

谢谢!

jri*_*sta 7

您应该能够创建一个派生自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
}
Run Code Online (Sandbox Code Playgroud)

从技术上讲,由于DataContext继承了ObjectContect中的所有内容,因此IDConContext的实现由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
    }
}
Run Code Online (Sandbox Code Playgroud)