gpt4 book ai didi

c# - 在进行单元测试时,应该如何处理嵌套的 ViewModel?

转载 作者:行者123 更新时间:2023-11-30 21:54:27 25 4
gpt4 key购买 nike

我正在为项目中的 ViewModel 创建一些单元测试。我真的没有遇到问题,因为它们中的大多数都非常简单,但是当我在我的其他 ViewModel 中有一个新的(未完成的)ViewModel 时遇到了问题。

public class OrderViewModel : ViewModelBase
{
public OrderViewModel(IDataService dataService, int orderId)
{
\\ ...

Payments = new ObservableCollection<PaymentViewModel>();
}

public ObservableCollection<PaymentViewModel> Payments { get; private set; }

public OrderStatus Status { ... } //INPC

public void AddPayment()
{
var vm = new PaymentViewModel();

payments.Add(vm);

// TODO: Subscribe to PaymentViewModel.OnPropertyChanged so that
// if the payment is valid, we update the Status to ready.
}
}

我想创建一个单元测试,以便如果我的 PaymentViewModel 的任何 IsValid 属性发生变化并且所有属性都为真,则 Status 应该是 OrderStatus.Ready。我可以实现该类,但让我担心的是,如果问题出在 PaymentViewModel 中,我的单元测试将会中断。

我不确定这是否可行,但感觉我不应该担心 PaymentViewModel 是否正常运行以便对 进行单元测试OrderViewModel 是正确的。

public void GivenPaymentIsValidChangesAndAllPaymentsAreValid_ThenStatusIsReady()
{
var vm = new OrderViewModel();

vm.AddPayment();
vm.AddPayment();

foreach (var payment in vm.Payments)
{
Assert.AreNotEqual(vm.Status, OrderStatus.Ready);

MakePaymentValid(payment);
}

// Now all payments should be valid, so the order status should be ready.
Assert.AreEqual(vm.Status, OrderStatus.Ready);
}

问题是,我该如何编写 MakePaymentValid 才能保证 PaymentViewModel 的行为不会对我的单元测试产生负面影响?因为如果是这样,那么我的单元测试将失败,因为另一段代码不起作用,而不是我的代码。或者,如果 PaymentViewModel 也错误,它是否应该失败?我只是因为我认为如果 PaymentViewModel 有错误,我对 OrderViewModel 的测试应该失败。

我意识到我总是可以像使用 IDataService 那样创建一个接口(interface),但在我看来,让每个 ViewModel 都有一个接口(interface)并注入(inject)其中有点矫枉过正一些如何?

最佳答案

当谈到单元测试时,您绝对应该将测试与任何外部依赖项分开。请记住,这并不意味着您必须传入某个接口(interface);您会遇到正在使用特定类的情况,无论该类是否在您的控制范围内。

想象一下,您依赖的不是您的示例,而是 DateTime.Now。有些人会争论将其抽象为某种接口(interface) IDateTimeService,这可能会起作用。或者,您可以利用 Microsoft Fakes:垫片和 stub 。

Microsoft Fakes将允许您创建 Shim* 实例。关于这个主题有很多内容需要讨论,但 Microsoft 提供的图像说明 Fakes 的使用超出了您无法控制的类别(它也包括您控制范围内的组件)。

Microsoft Fakes Shims/Stubs

请注意您正在测试的组件 (OrderViewModel) 应如何与 System.dll(即 DateTime.Now)、其他组件(PaymentViewModel),以及外部项目(如果您依赖数据库或 Web 服务)。 Shim 用于伪造类,而 Stub 用于伪造(模拟)接口(interface)。


添加 Fakes 程序集后,只需使用 ShimPaymentViewModel 类即可提供您期望的行为。如果出于某种原因,真正的 PaymentViewModel 类行为不当并且您的应用程序崩溃,您至少可以确信问题不是由 OrderViewModel 引起的。当然,要避免这种情况,您应该为 PaymentViewModel 包含一些单元测试,以确保无论其他类正在使用它或如何使用它,它都能正常运行。

长话短说;

是的,在使用 Microsoft Fakes 进行测试时完全隔离您的组件。哦,Microsoft Fakes 确实可以很好地与其他框架配合使用,所以不要因为使用它而放弃其他选择;它与其他框架结合使用。

关于c# - 在进行单元测试时,应该如何处理嵌套的 ViewModel?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33108616/

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