【问题标题】:Unittesting Repositories using mocks使用模拟的单元测试存储库
【发布时间】:2016-01-15 10:38:04
【问题描述】:

我正在尝试编写单元测试。这是我第一次使用存储库和依赖注入来执行此操作。

我的单元测试如下:

[TestClass()]
public class PersonRepositoryTests
{
    Mock<PersonRepository> persoonRepository;
    IEnumerable<Person> personen;

    [TestInitialize()]
    public void Initialize()
    {
        persoonRepository = new Moq.Mock<PersonRepository >();
        personen = new List<Person>() { new Person { ID = 1, Name = "Bart Schelkens", GewerkteDagen = 200, Leeftijd = 52, Type = "1" },
                                        new Person { ID = 2, Name = "Yoram Kerckhofs", GewerkteDagen = 190, Leeftijd = 52, Type = "1" }};

        persoonRepository.Setup(x => x.GetAll()).Returns(personen);

    }

    [TestMethod()]
    public void GetAll()
    {
        var result = persoonRepository.Object.GetAll();
    }
}

我的仓库:

 public class PersonRepository
{
    DatabaseContext DbContext { get; }

    public PersonRepository(DatabaseContext dbContext)
    {
        this.DbContext = dbContext;
    }

    public virtual IEnumerable<Person> GetAll()
    {
        return DbContext.Persons.ToList();
    }

}

现在当我运行测试时,我收到以下错误:

"无法实例化类的代理:CoBen.Dossier.DataAccess.Repository.PersonRepository。 找不到无参数构造函数。”

所以我做错了什么,但我没有看到。 谁能帮帮我?

【问题讨论】:

  • 阅读错误信息...
  • @Steve:我知道它在说什么,我只是没有成功添加数据库上下文
  • 请记住,当您模拟存储库时,存储库中的代码永远不会被调用,因为模拟“拦截”调用并返回您指定的值。因此,您可以将存储库方法提取到接口并模拟它。

标签: c# unit-testing dependency-injection mocking repository


【解决方案1】:

发生该错误是因为在您的单元测试中您模拟了存储库,但您的存储库类似乎依赖于数据上下文。

您需要在存储库中添加一个默认构造函数,该构造函数没有数据上下文作为依赖项,如下所示:

公共 PersonRepository()

或模拟数据上下文。希望有帮助

【讨论】:

  • 如果我也想模拟数据上下文怎么办?
  • 我建议例如为您的数据库上下文使用标记界面。
  • 如果您要模拟数据上下文,那么您必须模拟存储库,因为模拟存储库不会调用数据上下文模拟。
  • 例如 public PersonRepository(IDatabaseContext context) 。然后,在您的单元测试中,您可以创建一个 mock 并设置您的存储库 = new PersonRepository(MockDatabaseContext)()。这有帮助吗?
【解决方案2】:

您正在模拟您的被测系统 (sut),即 PersonRepository,而您需要模拟的是它的依赖项:

[TestMethod]
public void GetAll()
{
    // *Arrange*
    var mockSet = new Mock<DbSet<Person>>(); 

    var mockContext = new Mock<DatabaseContext>(); 
    mockContext.Setup(m => m.Person).Returns(mockSet.Object); 

    // Configure the context to return something meaningful

    var sut = new PersonRepository(mockContext.Object);

    // *Act*
    var result = sut.GetAll()

    // *Assert* that the result was as expected
}

这有点“空中代码”,因为您的问题没有关于如何配置 DbContext 位的详细信息。

MSDN 上有一个worked example

【讨论】:

    【解决方案3】:

    尝试添加一个无参数的构造函数:)

    public PersonRepository(){}
    

    【讨论】:

    • 但是如果我想要带参数的构造函数呢?我将如何注入数据库上下文?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-05
    • 2014-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-09
    相关资源
    最近更新 更多