简体   繁体   English

我应该如何测试?

[英]How should I test this?

I have a ViewModel, which when initialized, creates a list of objects. 我有一个ViewModel,它在初始化时会创建一个对象列表。 These objects are created by resolving interface implementation from IoC. 这些对象是通过解决IoC的接口实现而创建的。

ViewModel 视图模型

    public class ApplianceViewModel : IAppliance
    {
        private List<IHardware> HardwareItems {get; set;}

        public ApplianceViewModel()
        {
            HardwareItems = new List<IHardware>();
            var hardware1 = Constants.Kernel.Get<IHardware>();
            var hardware2 = Constants.Kernel.Get<IHardware>();

            HardwareItems.Add(hardware1);
            HardwareItems.Add(hardware2);           
        }
    }

Unit Test 单元测试

[TestClass]
public class ApplicanceViewModelTest
{
    [TestMethod]
    public void TestSomething()
    {
        //Arrange
        var appliance = new ApplianceViewModel(); //This would fail to construct

    }
}

The above initialization would fail as the kernel would be null. 由于kernel为空,因此上述初始化将失败。 Basically, it tells me that having a constant class and accessing kernel directly is a bad design. 基本上,它告诉我拥有一个常量类并直接访问内核是一个糟糕的设计。

But then how would I modify my viewmodel 's constructor so that I can initialize a list, in other words make it testable? 但是,然后我将如何修改viewmodel的构造函数,以便初始化列表,换句话说,使其可测试?

Thank you. 谢谢。

But then how would I modify my viewmodel's constructor so that I can initialize a list, in other words make it testable? 但是然后我将如何修改我的viewmodel的构造函数,以便可以初始化列表,换句话说,使其可测试?

You inject it with implementations of the IHardware interface: 您将其与IHardware接口的实现一起注入:

public class ApplianceViewModel : IAppliance
{
    private List<IHardware> HardwareItems {get; set;}

    public ApplianceViewModel(IHardware hardware1, Hardware hardware2)
    {
        HardwareItems = new List<IHardware>();
        var hardware1 = hardware1;
        var hardware2 = hardware2;

        HardwareItems.Add(hardware1);
        HardwareItems.Add(hardware2);           
    }
}

So at runtime you could inject the view model with your existing constants: 因此,在运行时,您可以使用现有常量注入视图模型:

var appliance = new ApplianceViewModel(Constants.Kernel.Get<IHardware>(), Constants.Kernel.Get<IHardware>());

...and in your unit test project you pass in some other implemenation of the same interface: ...并且在您的单元测试项目中,您传递了相同接口的其他实现:

IHardware testHardware = new TestHardware();
var appliance = new ApplianceViewModel(testHardware, testHardware);

You will need to implement this "TestHardware" class in a way that makes your test pass. 您将需要通过使您的测试通过的方式来实现此“ TestHardware”类。 Using a mocking framework will be useful. 使用模拟框架将很有用。 Please refer to the following link for more information about this: http://codetunnel.io/what-is-a-mocking-framework-why-is-it-useful/ 请参考以下链接以获取有关此的更多信息: http : //codetunnel.io/what-is-a-mocking-framework-why-is-it-useful/

You can have another interface, ie IHardwareStuff , that will return a list of IHardware objects. 您可以具有另一个接口,即IHardwareStuff ,该接口将返回IHardware对象的列表。 The IHardwareStuff gets passed as an argument into the constructor of your ViewModel. IHardwareStuff作为参数传递给ViewModel的构造函数。 It's resolved by the dependency injection container and you can input a test implementation when you want to. 它由依赖项注入容器解决,您可以在需要时输入测试实现。

By doing this separation, you split your object into a value object and a service object . 通过这种分离,您可以将您的对象分为一个值对象和一个服务对象 The first one you create by doing new and passing some concrete values to it. 通过执行new并将一些具体值传递给它来创建第一个。 The latter is created by the dependency injection container and doesn't have concrete values passed into it as a constructor. 后者是由依赖项注入容器创建的,没有作为构造函数传递给它的具体值。

You can than write unit tests for both objects. 然后,您可以为两个对象编写单元测试。

For a good and testable design it's better if constructors do nothing, validation or variable assignment. 对于良好且可测试的设计,最好让构造函数不执行任何操作,验证或变量分配。

I suggesto to inject in the constructor of ApplianceViewModel the list HardwareItems . 我建议在ApplianceViewModel的构造函数中注入HardwareItems列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何正确测试IoC服务? - How should I test IoC services properly? 我应该如何在 WebAPI 集成测试中断言? - How should I assert in WebAPI integration test? 我应该测试模型吗? - Should I test a Model? 如何对返回XML的“存储库”进行单元测试? - How should I unit test a “repository” that returns XML? 使用Automapper映射ViewModel之后我应该测试什么? - After using Automapper to map a ViewModel how and what should I test? XUnit 如何对业务对象进行单元测试,我应该嘲笑一切吗? - XUnit how to unit test business object and should I be mocking everything? 我应该如何检查工厂在单元测试中创建的 object 图 - How should I inspect the object graph created by a factory in a unit test 我应该测试UDP服务器代码,如果是的话 - 为什么以及如何? - Should I test UDP server code, and if so - why and how? 我应该如何对使用Entity Framework实现的存储库方法进行单元测试? - How should I unit test a repository method implemented with Entity Framework? 我应该如何对返回模型的控制器进行单元测试? - How should I unit test a controller that returns a model?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM