我试图模拟我的通用存储库的dbset的where子句,并且不知道为什么我得到了System.NotSupported Exception。 我很嘲笑,所以我不知道为什么会发生这种情况。
private List<StubEntity> _data;
private Repository<StubEntity> _repository;
[TestInitialize]
public void TestInitialize()
{
_data = new List<StubEntity>
{
new StubEntity {Id = 1, Name = "Entity 1"},
...
};
var queryableData = _data.AsQueryable();
var mockDbSet = new Mock<DbSet<StubEntity>>();
mockDbSet
.Setup(m => m.Where(It.IsAny<Expression<Func<StubEntity, bool>>>()))
.Returns<Expression<Func<StubEntity, bool>>>(p => queryableData.Where(p));
var context = new Mock<StubContext>();
context.Setup(x => x.DbEntities).Returns(mockDbSet.Object);
context.Setup(x => x.Set<StubEntity>()).Returns(mockDbSet.Object);
_repository = new Repository<StubEntity>(context.Object);
}
我只测试where子句进入测试
[TestMethod]
public void Find_ReturnsProperEntity()
{
var entity = _repository.Find(s => s.Id == 1);
....
}
其中Find方法只调用上下文的where子句。
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return Context.Set<TEntity>().Where(predicate);
}
答案 0 :(得分:0)
Moq与non-virtual
成员(方法/属性)存在问题,并在遇到异常时抛出异常。
例如:
System.NotSupportedException:System.NotSupportedException:无效 在非虚拟(在VB中可覆盖)成员上设置:x =&gt; x.DbEntities。
这里的假设是你的StubContext
看起来像这样......
public class StubContext : DbContext {
//...code removed for brevity
public DbSet<StubEntity> DbEntities { get; set; }
//...other code removed for brevity
}
...应该使用像...这样的虚拟属性进行编辑。
public class StubContext : DbContext {
//...code removed for brevity
public virtual DbSet<StubEntity> DbEntities { get; set; }
//...other code removed for brevity
}
使用以下实用程序类
using Moq;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
public static class MockDbSet {
public static Mock<DbSet<T>> Create<T>(params T[] elements) where T : class {
return elements.AsDbSetMock();
}
}
public static class MockDbSetExtensions {
public static Mock<DbSet<T>> AsDbSetMock<T>(this IEnumerable<T> list) where T : class {
IQueryable<T> queryableList = list.AsQueryable();
Mock<DbSet<T>> dbSetMock = new Mock<DbSet<T>>();
dbSetMock.As<IQueryable<T>>().Setup(x => x.Provider).Returns(queryableList.Provider);
dbSetMock.As<IQueryable<T>>().Setup(x => x.Expression).Returns(queryableList.Expression);
dbSetMock.As<IQueryable<T>>().Setup(x => x.ElementType).Returns(queryableList.ElementType);
dbSetMock.As<IQueryable<T>>().Setup(x => x.GetEnumerator()).Returns(() => queryableList.GetEnumerator());
return dbSetMock;
}
}
我使用模拟的DbSet
和建议的修复程序重新创建了单元测试...
[TestClass]
public class MockDbSetTests {
private List<StubEntity> _data;
private Repository<StubEntity> _repository;
[TestInitialize]
public void TestInitialize() {
_data = new List<StubEntity>
{
new StubEntity {Id = 1, Name = "Entity 1"},
//...
};
var mockDbSet = _data.AsDbSetMock();
var context = new Mock<StubContext>();
context.Setup(x => x.DbEntities).Returns(mockDbSet.Object);
context.Setup(x => x.Set<StubEntity>()).Returns(mockDbSet.Object);
_repository = new Repository<StubEntity>(context.Object);
}
[TestMethod]
public void Find_Should_Return_Proper_Entity() {
//Act
var entity = _repository.Find(s => s.Id == 1);
//Assert
Assert.IsNotNull(entity);
Assert.IsTrue(entity.Count() == 1);
}
}
......它通过了(绿色)。