2017-01-25 59 views
2

我的问题与How do I trigger a ngModel model update in an Angular 2 unit test?angular2单元测试未检测到输入变化

完全相同我在测试中必须做些愚蠢的事情。任何人都可以指出的是,我俯瞰

组件的任何明显的错误

@Component({ 
    moduleId: module.id, 
    selector: 'od-tree', 
    templateUrl: 'tree.component.html', 
    styleUrls: ['tree.component.css'], 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class TreeComponent implements OnInit, OnChanges, AfterViewChecked { 
    @Input() allResources: { items: {} }; 
    @Input() resourceGroups = { items: {} }; 
    @Input() selectedNodes: ITree.SelectedNode[]; 
    @Input() showIcons: boolean; 
    @Input() showCheckboxes: boolean; 
    @Input() omitAncillaryDBs: boolean; 

    @Output() selectNode = new EventEmitter<any>(); 

    searchResource$ = new Subject<string>(); 
    searchField = ''; 
    tabs = [ 
    { title: TABS.ALL_RESOURCES, active: true }, 
    { title: TABS.RESOURCE_GROUPS, active: false } 
    ]; 
    inSearchMode = false; 
    trees = { 
    ALL_RESOURCES: { 
     searchText: null, 
     tree: [] 
    }, 
    RESOURCE_GROUPS: { 
     searchText: null, 
     tree: [] 
    } 
    }; 

    private _allResourcesTreeState = []; 
    private _resourceGroupsTreeState = []; 
    private ancillaryDBList = ['App-Services', 'Documents', 'Extensions', 'Fab', 'Last-Login', 
    'Meters', 'Modules', 'Schemas', 'Security', 'Triggers']; 

    constructor(private _cd: ChangeDetectorRef) { } 
... 
... 
... 
} 

模板

<div class="input-with-icon"> 
     <i class="icon-search"></i> 
     <input type="text" [(ngModel)]="searchField" name="searchField" class="form-control" id="search-resources" placeholder="Search" (ngModelChange)="searchResource$.next(searchField)"> 
     </div> 
... (truncated) 
.... 
.... 

单元测试

describe('tree component',() => { 
    //let activatedRoute: ActivatedRouteStub; 
    let comp: TreeComponent; 
    let fixture: ComponentFixture<TreeComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 


    beforeEach(async(() => { 
     TestBed.configureTestingModule({ 
     imports: [TreeModule], 
     }) 
     .compileComponents(); 
    })); 

    beforeEach(() => { 
     fixture = TestBed.createComponent(TreeComponent); 
     comp = fixture.componentInstance; 
     de = fixture.debugElement; 
     el = de.nativeElement; 
     comp.ngOnInit(); 
     fixture.detectChanges(); 
    }); 


    it('should bind value to ngmodel',() => { 
     let inputEl = de.query(By.css('input#search-resources')) 
     inputEl.nativeElement.value = 'node'; 
     inputEl.triggerEventHandler('input', {target: inputEl.nativeElement}); 
     fixture.detectChanges(); 
     expect(comp.searchField).toEqual('node'); 
     }); 

// another approach 
    it('should filter resources when used in host component',fakeAsync(() => { 
     let inputEl = de.query(By.css('input#search-resources')); 
     inputEl.nativeElement.value = 'node'; 
     dispatchEvent('input', inputEl.nativeElement); 
     tick(); 
     fixture.detectChanges(); 
     expect(de.queryAll(By.css('li.host-leaf:not([hidden])')).length).toEqual(2, 'should show filtered hosts'); 
    })); 

    } 
+0

更新您的文章有**的** TreeComponent – Aravind

回答

3

这是与当前Testbed实现detectChanges()结合使用OnPush更改检测策略时的已知错误。你可以在这里读更多关于它的内容。确实很烦人。

原来,@Input变化不是从当前组件本身触发,而是从父组件触发。

这里是我做的,使我的测试与角V2.4

fixture.changeDetectorRef['internalView']['compView_0'].markAsCheckOnce(); 
fixture.detectChanges(); 

https://github.com/angular/angular/issues/12313

+0

呵呵!非常感谢你。我还没有尝试,但我会接受这个答案。 – Sudhakar

0

您需要将FormsModule导入测试模块以使ngModel绑定正常工作。

beforeEach(async(() => { 
    TestBed.configureTestingModule({ 
    imports: [ 
    TreeModule 
    FormsModule 
    ] 
    }) 
    .compileComponents(); 
})); 
+0

FormsModule已经在TreeModule进口工作。我也尝试了你的建议,但没有帮助。 – Sudhakar