使用最小起订量和通用存储库进行单元测试
Unit testing with Moq and a Generic Repository
我正在用最小起订量创建我的第一个测试单元,但似乎无法正常工作。
我有一个注入我的 ApplicationDbContext 的通用存储库。我正在尝试接收存储在数据库中的所有食物的列表。在我的实际服务中,我使用 Simple Injector,一切正常。
ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext()
: base("ApplicationDbContext")
{
}
...
}
通用存储库:
public class Repository<T> : IRepository<T> where T : class
{
private ApplicationDbContext _context;
private readonly IDbSet<T> _entities;
public Repository(ApplicationDbContext context)
{
_context = context;
_entities = _context.Set<T>();
}
.. async methods .. (GetAllAsync)
}
起订量测试:
[TestClass]
public class FoodServicesTest
{
private Mock<IRepository<Food>> _foodRepository;
[TestInitialize]
public void Initialize()
{
_foodRepository = new Mock<IRepository<Food>>();
}
[TestMethod]
public async Task CanGetAllFoods()
{
// Before edit 2
//IList<Food> foods = await _foodRepository.Object.GetAllAsync();
//_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foods);
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(List<Food>());
IList<Food> foods = await _foodRepository.Object.GetAllAsync();
Assert.IsTrue(foods.Count >= 1);
}
}
编辑 2:
将设置置于 GetAllAsync() 之上(感谢 Patrick Quirk)并将其参数替换为 'new List()' 之后,食物列表不再 return 为 null,而是计数 0,大概是更好,但我希望它是 2(就像在服役中一样)。
return 值为空列表。这是由您的这行代码指定的
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(new List<Food>());
上面的指令实际上是在调用 GetAllAsync 时告诉模拟对象 return 一个新的空列表。
您应该改为创建新的 Food 对象 "simulate" 来自数据库的结果,如下所示:
var foodList = new List<Food>();
foodList.Add(new Food() { ...insert your mocked values here });
foodList.Add(new Food() { ...insert your mocked values here });
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foodList);
编辑
仔细查看代码,我只能看到您只是在使用模拟对象并查看 return 是否有结果。你确定真的需要这个测试吗?当需要测试一些业务逻辑时,在存储库上使用模拟对象很有用。也许您的代码只是为了提出问题而被重写,但值得指出这一点。
您可以这样指定 return 的值:
var foods=new List<Food>();
//// add two items here
foods.Add(new food(){.. set values });
foods.Add(new food(){.. set values });
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foods);
IList<Food> foods = await _foodRepository.Object.GetAllAsync();
我正在用最小起订量创建我的第一个测试单元,但似乎无法正常工作。
我有一个注入我的 ApplicationDbContext 的通用存储库。我正在尝试接收存储在数据库中的所有食物的列表。在我的实际服务中,我使用 Simple Injector,一切正常。
ApplicationDbContext:
public class ApplicationDbContext : IdentityDbContext<AppUser>
{
public ApplicationDbContext()
: base("ApplicationDbContext")
{
}
...
}
通用存储库:
public class Repository<T> : IRepository<T> where T : class
{
private ApplicationDbContext _context;
private readonly IDbSet<T> _entities;
public Repository(ApplicationDbContext context)
{
_context = context;
_entities = _context.Set<T>();
}
.. async methods .. (GetAllAsync)
}
起订量测试:
[TestClass]
public class FoodServicesTest
{
private Mock<IRepository<Food>> _foodRepository;
[TestInitialize]
public void Initialize()
{
_foodRepository = new Mock<IRepository<Food>>();
}
[TestMethod]
public async Task CanGetAllFoods()
{
// Before edit 2
//IList<Food> foods = await _foodRepository.Object.GetAllAsync();
//_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foods);
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(List<Food>());
IList<Food> foods = await _foodRepository.Object.GetAllAsync();
Assert.IsTrue(foods.Count >= 1);
}
}
编辑 2:
将设置置于 GetAllAsync() 之上(感谢 Patrick Quirk)并将其参数替换为 'new List()' 之后,食物列表不再 return 为 null,而是计数 0,大概是更好,但我希望它是 2(就像在服役中一样)。
return 值为空列表。这是由您的这行代码指定的
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(new List<Food>());
上面的指令实际上是在调用 GetAllAsync 时告诉模拟对象 return 一个新的空列表。
您应该改为创建新的 Food 对象 "simulate" 来自数据库的结果,如下所示:
var foodList = new List<Food>();
foodList.Add(new Food() { ...insert your mocked values here });
foodList.Add(new Food() { ...insert your mocked values here });
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foodList);
编辑
仔细查看代码,我只能看到您只是在使用模拟对象并查看 return 是否有结果。你确定真的需要这个测试吗?当需要测试一些业务逻辑时,在存储库上使用模拟对象很有用。也许您的代码只是为了提出问题而被重写,但值得指出这一点。
您可以这样指定 return 的值:
var foods=new List<Food>();
//// add two items here
foods.Add(new food(){.. set values });
foods.Add(new food(){.. set values });
_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(foods);
IList<Food> foods = await _foodRepository.Object.GetAllAsync();