gpt4 book ai didi

c# - 实例化其他类的单元测试类

转载 作者:行者123 更新时间:2023-12-03 10:25:18 26 4
gpt4 key购买 nike

我正在尝试为一个在其中实例化其他类的类编写单元测试,但我正在努力解决如何以可测试的方式实例化这些类。我知道依赖注入(inject),但这有点不同,因为实例化不会发生在构造函数中。

这个问题实际上并不特定于 MVVM 和 C#,但这就是我的示例将使用的内容。请注意,我已经对此进行了简化,它不会按原样编译 - 目标是显示一个模式。

class ItemListViewModel
{
ItemListViewModel(IService service)
{
this.service.ItemAdded += this.OnItemAdded;
}

List<IItemViewModel> Items { get; }

OnItemAdded(IItemModel addedItem)
{
var viewModel = new ItemViewModel(addedItem);
this.Items.Add(viewModel);
}
}

class ItemViewModel : IItemViewModel
{
ItemViewModel(IItem) {}
}

从上面可以看出,模型层有一个事件。 ViewModel 监听该事件,并作为响应添加一个新的子 ViewModel。这符合我所知道的标准面向对象编程实践以及 MVVM 模式,并且对我来说感觉像是一个非常干净的实现。

当我想对这个 ViewModel 进行单元测试时,问题就来了。虽然我可以使用依赖注入(inject)轻松模拟服务,但我无法模拟通过事件添加的项目。这引出了我的主要问题: 是否可以根据 ItemViewModel 的真实版本而不是模拟来编写我的单元测试?

我的直觉是:这不行,因为我现在测试的不仅仅是 ItemListViewModel,特别是如果 ItemListViewModel 在内部调用任何项目的任何方法。我应该让 ItemListViewModel 在测试期间依赖于模拟 IItemViewModels。

对于如何做到这一点,我考虑了一些策略:
  • 让 ItemListViewModel 的所属类监听事件并添加模拟项目。不过,这只是解决了问题,因为现在不能完全模拟出所属类。
  • 将 ItemViewModel 工厂传递给 ItemListViewModel 并使用它而不是 new。这肯定适用于模拟,因为它将基于依赖注入(inject)的东西移动......但这是否意味着我需要一个工厂来处理我想要在我的应用程序中模拟的每个类?这感觉不对,维护起来会很痛苦。
  • 重构我的模型以及它如何与 ViewModel 通信。也许我使用的事件模式不适合测试;虽然我不知道我将如何解决需要最终在需要测试的代码中的某处构造一个 ItemViewModel 的问题。

  • 此外,我在网上搜索并浏览了 Clean Code 这本书,但这确实没有涉及。一切都在谈论依赖注入(inject),这并没有明确解决这个问题。

    最佳答案

    is it OK to write my unit tests depending on the real version of ItemViewModel, rather than a mock?



    是的!
    只要测试变得缓慢或设置起来非常复杂,您就应该使用真正的实现。

    请注意,测试应该是隔离的,但应该与其他测试隔离,而不是与被测单元的其他依赖项隔离。

    测试的主要问题是应用程序使用共享状态(数据库、文件系统)。共享状态使我们的测试相互依赖(添加和删除项目的测试不能并行运行)。通过引入模拟,我们消除了测试之间的共享状态。

    有时应用程序被划分为独立的域模块,这些模块通过抽象接口(interface)相互“通信”。为了保持模块的独立性,我们将模拟通信接口(interface),因此被测模块将不依赖于另一个域模块的实现细节。

    从字面上模拟所有依赖项将使维护/重构更改成为一场噩梦,因为每次您将一些逻辑提取到专用类中时,您将被迫更改/重写您正在重构的单元的测试套件。

    您的场景是一个很好的例子,通过不模拟创建 ItemViewModel ,您将能够引入工厂将其注入(inject)测试下的类并运行现有的测试套件以确保工厂没有引入任何回归。

    关于c# - 实例化其他类的单元测试类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60330954/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com