在单元测试中使用依赖注入对象是个坏主意吗?

Tim*_*sen 2 testing nunit dependency-injection

我不确定我在做什么实际上是使用 DI 进行单元测试的“正确”方式。现在我要求我的 ViewModelLocator 实际创建我需要的所有实例,然后获取我需要测试的实例,这使得测试单个实例变得非常简单,因为让我们假设 Receipt 需要创建一个 Reseller 对象,经销商需要一个要创建的用户对象,用户需要创建一些其他对象,这会创建一系列对象来创建只是为了测试单个实例。

使用通常的接口将被模拟并解析为您想要创建的对象,但是简单的实体/视图模型如何?

在涉及 DI 的情况下进行单元测试的最佳实践是什么?

 public class JournalTest
{
    private ReceiptViewModel receipt;
    private ViewModelLocator locator;
    [SetUp]
    public void SetUp()
    {
        locator = new ViewModelLocator();

        receipt = SimpleIoc.Default.GetInstance<ReceiptViewModel>();
    }
    [TearDown]



    [Test]
    public void CheckAndCreateNewJournal_Should_Always_Create_New_Journal()
    {
        receipt.Sale.Journal = null;
        receipt.Sale.CheckAndCreateNewJournal();
        Assert.NotNull(receipt.Sale.Journal);
    }

}
Run Code Online (Sandbox Code Playgroud)

Tse*_*eng 5

首先,您没有在代码中使用依赖注入。您拥有的称为服务定位器(服务定位器与 IoC/服务定位器紧密耦合并使其难以测试)。

是的,这很糟糕(服务定位器和依赖注入),因为这意味着:您不是在进行单元测试,而是在进行集成测试。

在您的情况下,ReceiptViewModel不会单独测试,但您的测试还会测试依赖项ReceiptViewModel(即存储库、注入的服务等)。这称为集成测试。

UnitTest 必须只测试有问题的类,而没有依赖项。您可以通过存根(依赖项的虚拟实现,假设您使用接口作为依赖项)或使用模拟(使用像 Moq 这样的模拟框架)来实现这一点。

哪个更容易/更好,因为您不必实现整个类,而只需为您知道测试用例所需的方法设置模拟。

作为附加说明,您必须自己创建实体。根据您的 UnitTest 框架,可能有数据驱动的测试(通过测试方法上的属性),或者您只是在代码中创建它们,或者如果您在许多类中使用了模型/实体,请为其创建一个辅助方法。

不应将视图模型注入构造函数(至少避免),因为它将它们紧密耦合