2016-12-01 12 views
3

Я использую EF6. Сгенерированный код что-то вроде:Ед. Изм. С Moq - Значение не может быть пустым

public partial class MyDataContext : DbContext 
{ 
    public MyDataContext() : base("name=mydata") 
    { 
    } 

    public virtual DbSet<Book> Books { get; set; } 
} 

Тогда у меня есть общий репозиторий, как:

public class GenericRepository<TObject> where TObject : class 
{ 
    protected readonly MyDataContext Context; 

    protected GenericRepository(MyDataContext context) 
    { 
     Context = context; 
    } 

    public virtual DbSet<TObject> GetAll() 
    { 
     return Context.Set<TObject>(); 
    } 
} 

Тогда у меня есть сервис, который использует GenericRepository вернуть данные:

public class MyDataService<TObject> where TObject : class 
{ 
    private readonly MyDataContext context; 

    public MyDataService(MyDataContext ct) 
    { 
     context = ct; 
    } 

    public ICollection<TObject> GetAll() 
    { 
     var r = new GenericRepository<TObject>(context); 
     return r.GetAll().ToList(); 
    } 
} 

Так Я могу получить все книги с чем-то вроде этого:

var ds = new MyDataService<Book>(new MyDataContext()); 
var data = ds.GetAll(); 

Это прекрасно работает. Далее я пытаюсь использовать Moq для модульного тестирования код выше с чем-то вроде:

var books = new List<Book> 
{ 
    new Book {Id = 1, Name = "BBB"}, 
    new Book {Id = 2, Name = "ZZZ"}, 
    new Book {Id = 3, Name = "AAA"}, 
}.AsQueryable(); 

var mockSet = new Mock<DbSet<Book>>(); 
mockSet.As<IQueryable<Book>>().Setup(m => m.Provider).Returns(books.Provider); 
mockSet.As<IQueryable<Book>>().Setup(m => m.Expression).Returns(books.Expression); 
mockSet.As<IQueryable<Book>>().Setup(m => m.ElementType).Returns(books.ElementType); 
mockSet.As<IQueryable<Book>>().Setup(m => GetEnumerator()).Returns(books.GetEnumerator()); 

var mockContext = new Mock<MyDataContext>(); 
mockContext.Setup(c => c.Books).Returns(mockSet.Object); 

var service = new MyDataService<Book>(mockContext.Object); 
var data = service.GetAll(); 

Однако я получаю ошибку "Value cannot be null.\r\nParameter name: source" на последней строке. Когда я вхожу в код, я вижу, что коллекция Books в контексте объекта пуста.

Что я делаю неправильно?

+0

вам действительно нужно MOq 'DbSet' (я полагаю, нет), вы можете рассчитывать на EF, не проверить это делать. –

ответ

2

Это потому, что тест устанавливает .Setup(c => c.Books) в контексте данных, но в действительности код обращается к Context.Set<TObject>() в методе GetAll(), поэтому для тестирования он будет в конечном итоге как null.

попробуйте изменить

mockContext.Setup(c => c.Set<Book>()).Returns(mockSet.Object); 
+0

да. Я понял, что сразу после того, как я разместил вопрос. Спасибо! – notlkk

Смежные вопросы