MoQ: свойство правильно установлено как виртуальное, но все еще имеет недопустимую настройку для не виртуального члена

Я хотел бы провести модульное тестирование DbContext, который наследуется от IdentityDbContext

Я получаю NotSupportedException сообщение об ошибке с очень распространенным сообщением:

System.NotSupportedException: неверная установка для не виртуального (переопределяемого в VB) члена

Чтобы найти подсказки, я уже прочитал кучу постов. Вот несколько примеров:

Очевидно, что решение, по-видимому, устанавливает dbSet как виртуальный. Что я сделал.

Не повезло, ошибка остается.

Вот мой IdentityDataContext:

public class IdentityDataContext : IdentityDbContext<ApplicationUser>
{      
    public virtual DbSet<Search> Searches { get; set; }

    public IdentityDataContext()
        : base("LocalDb",
              throwIfV1Schema: true)
    {            
    }

    public static IdentityDataContext Create()
    {
        return new IdentityDataContext();
    }
}

Вот мой поиск POCO:

public class Search : BaseEntity
{
    //BaseEntity is just an abstract class with createdAt,Id,updatedAt property
    public string ConsumerIdentifier { get; set; }
    public string LanguageCode { get; set; }         
}

Наконец, вот мой метод настройки:

[TestInitialize]
public void SetupTest()
{
    //DataInitializer.GetAllSearches() returns a List of "Search"

    _searches = DataInitializer.GetAllSearches();

    var dbSet = new Mock<DbSet<Search>>();
    dbSet.As<IQueryable<Search>>().Setup(m => m.Provider).Returns(_searches.AsQueryable().Provider);
    dbSet.As<IQueryable<Search>>().Setup(m => m.Expression).Returns(_searches.AsQueryable().Expression);
    dbSet.As<IQueryable<Search>>().Setup(m => m.ElementType).Returns(_searches.AsQueryable().ElementType);
    dbSet.As<IQueryable<Search>>().Setup(m => m.GetEnumerator()).Returns(_searches.AsQueryable().GetEnumerator());
    dbSet.Setup(d => d.Add(It.IsAny<Search>())).Callback<Search>(_searches.Add);

    _dataContextMock = new Mock<IdentityDataContext>()
    {
        CallBase = true
    };

    // The error appears here ---------------- _
    dataContextMock.Setup(x   => x.Searches).Returns(dbSet.Object);
    //----------------------------------------------------------------------

    _dataContextMock.Setup(x => x.Set<Search>()).Returns(dbSet.Object);

    _searchRepository = new SearchRepository(_dataContextMock.Object);
}

Что мне не хватает?

1 ответ

Решение

1) нет необходимости в модульном тестировании DbContext. Microsoft уже провела бы обширные испытания на нем.

2) если DbContext должен использоваться как зависимость для другого класса, тогда абстрагируйте dbcontext

public interface IDataContext {
    DbSet<Search> Searches { get; set; }
}

public class IdentityDataContext : IdentityDbContext<ApplicationUser>, IDataContext { ... }

public class SearchRepository {
    public SearchRepository(IDataContext context) { ... }
}

У вас нет занятий в зависимости от конкреций, а скорее от абстракций. IdentityDataContext это деталь реализации, о которой зависимые классы не должны знать

Это тогда позволило бы больше гибкости для тестирования

Mock<IDataContext> _dataContextMock;

[TestInitialize]
public void SetupTest() {

    //DataInitializer.GetAllSearches() returns a List of "Search"
    _searches = DataInitializer.GetAllSearches();
    var queryable = _searches.AsQueryable();

    var dbSet = new Mock<DbSet<Search>>();
    dbSet.As<IQueryable<Search>>().Setup(m => m.Provider).Returns(queryable.Provider);
    dbSet.As<IQueryable<Search>>().Setup(m => m.Expression).Returns(queryable.Expression);
    dbSet.As<IQueryable<Search>>().Setup(m => m.ElementType).Returns(queryable.ElementType);
    dbSet.As<IQueryable<Search>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator());
    dbSet.Setup(d => d.Add(It.IsAny<Search>())).Callback<Search>(_searches.Add);


    _dataContextMock = new Mock<IDataContext>();

    _dataContextMock.Setup(x => x.Searches).Returns(dbSet.Object);

    _dataContextMock.Setup(x => x.Set<Search>()).Returns(dbSet.Object);

    _searchRepository = new SearchRepository(_dataContextMock.Object);

}
Другие вопросы по тегам