我该怎么测试呢?

时间:2016-12-12 22:53:53

标签: c# wpf unit-testing mvvm ninject

我有一个ViewModel,在初始化时会创建一个对象列表。这些对象是通过解决IoC的接口实现而创建的。

视图模型

import {Component, NgModule, ViewChild} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {EditDirective} from './editDirective'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <p [contentEditable]="isEditable">click me to edit</p>
      <p [contentEditable]="isEditable">click me to edit with same directive</p>
      <button (click)="Edit()">Press me to enable editing</button>
    </div>
  `,
})
export class App {

isEditable: boolean = false;

Edit() {
   this.isEditable = true;
}

}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, EditDirective ],
  bootstrap: [ App ]

})
export class AppModule {}

单元测试

    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);           
        }
    }

上述初始化将失败,因为[TestClass] public class ApplicanceViewModelTest { [TestMethod] public void TestSomething() { //Arrange var appliance = new ApplianceViewModel(); //This would fail to construct } } 将为null。基本上,它告诉我,拥有一个常量类并直接访问内核是一个糟糕的设计。

但是接下来我将如何修改我的kernel构造函数以便初始化列表,换句话说使其可测试?

谢谢。

3 个答案:

答案 0 :(得分:1)

  

但是,我如何修改我的viewmodel的构造函数,以便我可以初始化一个列表,换句话说,使它成为可测试的?

您可以使用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);           
    }
}

因此,在运行时,您可以使用现有常量注入视图模型:

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

...在你的单元测试项目中,你传递了同一个接口的其他一些实现:

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

你需要实现这个&#34; TestHardware&#34;以一种让你的测试通过的方式上课。使用模拟框架将非常有用。有关详细信息,请参阅以下链接:http://codetunnel.io/what-is-a-mocking-framework-why-is-it-useful/

答案 1 :(得分:0)

您可以使用另一个界面,即IHardwareStuff,它将返回IHardware个对象的列表。 IHardwareStuff作为参数传递给ViewModel的构造函数。它由依赖注入容器解决,您可以在需要时输入测试实现。

通过执行此分离,您可以将对象拆分为值对象服务对象。您通过执行new并向其传递一些具体值来创建的第一个。后者由依赖注入容器创建,并且没有作为构造函数传递给它的具体值。

您可以为两个对象编写单元测试。

答案 2 :(得分:0)

对于一个好的和可测试的设计,如果构造函数什么也不做,验证或变量赋值,它会更好。

我建议在ApplianceViewModel列表HardwareItems的构造函数中注入。