使用Moq和Generic Repository进行单元测试

时间:2016-03-09 14:50:44

标签: c# unit-testing repository asp.net-identity moq

我正在使用Moq创建我的第一个测试单元,但似乎无法使其正常工作。

我有一个Generic存储库,它注入了我的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)
}

Moq测试:

[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()',食物列表不再返回null,但计数0可能更好但我希望它成为2(就像在服务中一样)。

2 个答案:

答案 0 :(得分:1)

返回值是一个空列表。这是由代码的这一行指定的

_foodRepository.Setup(m => m.GetAllAsync()).ReturnsAsync(new List<Food>());

上面的指令实际上告诉模拟对象在调用GetAllAsync时返回一个新的空列表。

您应该创建新的食物对象以模拟&#34;数据库的结果,如下所示:

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);

修改

更好地查看代码我只能看到你只是使用模拟对象并查看是否返回结果。你确定这个测试真的需要吗?当涉及要测试的一些业务逻辑时,在存储库上使用模拟对象很有用。也许你的代码只是为了提出问题而重写,但值得指出这一点。

答案 1 :(得分:0)

您可以指定以这种方式返回的值:

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();