我有一个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
构造函数以便初始化列表,换句话说使其可测试?
谢谢。
答案 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
的构造函数中注入。