【问题标题】:c# How to mock a list of objectsc# 如何模拟对象列表
【发布时间】:2017-09-13 06:19:32
【问题描述】:

在 C# 中,如何模拟对象列表?

我正在尝试一个练习,它指定在我的单元测试的安排部分中,我需要“模拟 Book 对象列表”。

创建 Book 对象的模拟列表的语法是什么?我曾尝试创建模拟 Book 对象并将它们添加到书籍列表中,但这不起作用。

public void Test_GetAllBooks_ReturnsListOfBooksItReceivesFromReadAllMethodOfReadItemCommand_WhenCalled()
{
    //Arrange
    Mock<ReadItemCommand> mockReadItemCommand = new Mock<ReadItemCommand>();
    Catalogue catalogue = new Catalogue(mockReadItemCommand.Object);

    Mock<Book> mockBook1 = new Mock<Book>();
    Mock<Book> mockBook2 = new Mock<Book>();
    List<Book> mockBookList = new List<Book>();
    mockBookList.Add(mockBook1);
    mockBookList.Add(mockBook2);

    mockReadItemCommand.Setup(r => r.ReadAll()).Returns(mockBookList);

    //Act
    List<Book> actual = catalogue.GetAllBooks();

    //Assert
    Assert.AreSame(mockBookList, actual);

}

这给了我 2 个编译错误,都是 CS1503,在我尝试将模拟书籍添加到我的类型 Book 列表的两行中。

【问题讨论】:

  • minimal reproducible example 中显示您迄今为止尝试过的内容。也许到那时,可以提供更好的帮助。该练习中的所有内容都可以在此站点中找到,因为它已经被询问过。
  • 我投票决定将此问题作为题外话结束,因为家庭作业问题必须显示您迄今为止尝试过的内容,并具体说明您遇到的问题。正如所写,这只是“给我代码”。
  • 好吧,对不起,我是软件开发的新手(因此是这个问题)和 StackOverflow 的新手 - 不需要对我的问题做出反应。我认为很明显我的问题是关于如何模拟对象列表的。现在请看我上面的代码。

标签: c# unit-testing mocking moq stubbing


【解决方案1】:

如果我没听错,您可以克隆列表: 例如如下所示:

How do I clone a generic list in C#?

您可以用相同的方式克隆它,或者您可以通过创建一个新列表并从源列表中添加每个元素的副本来自己复制该列表。 希望有帮助。

【讨论】:

  • 嗨,郊狼。谢谢你的建议。我是 C# 新手,所以请耐心等待。克隆与使用 Moq 模拟相同吗?使用模拟可以实现同样的效果吗?我被特别要求在这个练习中使用最小起订量。
【解决方案2】:

只需创建一个书籍列表来表示在执行被测方法时要返回的虚假/模拟数据。无需对假数据使用最小起订量。使用 Moq 模拟被测系统(Catalogue)的依赖项(ReadItemCommand

public void Test_GetAllBooks_ReturnsListOfBooksItReceivesFromReadAllMethodOfReadItemCommand_WhenCalled()
{
    //Arrange
    var mockReadItemCommand = new Mock<ReadItemCommand>();
    var catalogue = new Catalogue(mockReadItemCommand.Object);

    var expected = new List<Book>(){
        new Book {
            Title = "Book1", 
            //populate other properties  
        },
        new Book { 
            Title = "Book2", 
            //populate other properties  
        }
    };

    mockReadItemCommand
        .Setup(_ => _.ReadAll())
        .Returns(expected);

    //Act
    var actual = catalogue.GetAllBooks();

    //Assert
    Assert.AreSame(expected, actual);
}

【讨论】:

  • 感谢 Nkosi 的解决方案。这样就解决了编译错误的问题。但是,该练习指定了“您将需要模拟 Book 对象列表”和“您将需要存根模拟 ReadItemCommand 的 ReadAll() 方法以返回模拟图书列表”。所以我不需要模拟书列表或实际书对象的模拟列表吗?我被告知只有被测试的对象应该是真实的,测试中使用的所有其他对象都应该是模拟的。 [对不起,如果这些是愚蠢的问题,我发现嘲笑非常令人困惑!]
  • @MichaelHennigan 图书列表充当模拟数据源。它们不是来自实时持久数据的实际数据。因此他们是嘲笑者。实际的模拟是依赖项,书籍列表是模拟功能的一部分。唯一实际模拟 Book 对象的情况是实际对象单独影响主题的测试。
  • 好的,谢谢您的解释!我想我现在终于明白了。
猜你喜欢
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 2023-03-25
相关资源
最近更新 更多