Reputation: 256
Html:
<checkbox (change)="onChange()" [(ngModel)]="ngModel"> Checkbox </checkbox>
ts:
ngModel: boolean;
@Output() checkboxEvent = new EventEmitter<any>();
onChange() {
this.checkboxEvent.emit(this.ngModel);
}
test case:
it('TC 3: should emit an event on change of checkbox', async(() => {
spyOn(component.checkboxEvent, 'emit');
component.onChange();
const edlCheckbox = fixture.debugElement.query(By.css('checkbox ')).nativeElement;
edlCheckbox.dispatchEvent(new Event('change'));
fixture.detectChanges();
expect(component.checkboxEvent ).toHaveBeenCalled();
expect(component.checkboxEvent .emit).toHaveBeenCalledWith(true);
}));
Error:
Failed: <toHaveBeenCalled> : Expected a spy, but got EventEmitter(
{ _isScalar: false, observers: [ ], closed: false,
isStopped: false, hasError: false, thrownError: null,
__isAsync: false, emit: spy on emit }).
Usage: expect(<spyObj>).toHaveBeenCalled()
Upvotes: 1
Views: 2756
Reputation: 306
Ok I got this one working using the following with reactiveforms and faker in my test. You don't have to use Faker.
<div [formGroup]="todoItemFormGroup">
<input type="checkbox" (click)="checkedInput()" formControlName="isComplete" />
....
</div>
I'm using reactiveForm group
todoItemFormGroup = new FormGroup(
{
name: new FormControl('', [Validators.required]),
isComplete: new FormControl(false)
}
)
checkedInput() {
this.updateItemtoParent.emit({
...this.todoItem.getValue(), //this is my BehaviorSubject<TodoItemDto>
...this.todoItemFormGroup.getRawValue() as TodoItemDto, //this is from the formgroup
} as TodoItemDto);
}
and finally my spec looks like this:
it("Should emit the checklist item when the checkbox is checked", () => {
spyOn(component.updateItemtoParent, 'emit');
const fakeTodoItem: TodoItemDto = {
id: faker.datatype.uuid(),
name: faker.name.firstName(),
checklistId: faker.datatype.uuid(),
isComplete: false
};
component.todoItem.next(fakeTodoItem);
fixture.detectChanges();
const compiled = fixture.debugElement.query(By.css('input[type=checkbox]'));
compiled.nativeElement.click();
fixture.detectChanges();
expect((component.todoItemFormGroup.getRawValue() as TodoItemDto).isComplete).toEqual(true);
expect(component.updateItemtoParent.emit).toHaveBeenCalledWith(fakeTodoItem);
});
Upvotes: 0
Reputation: 31245
You can do it easier with a callback function :
// vvvv
it('TC 3: should emit an event on change of checkbox', (done) => {
// vvvv
component.checkboxEvent.subscribe(() => done());
fixture.debugElement.query(By.css('checkbox ')).nativeElement.click()
}
By using a done
function, the test will fail if the done
function is not called within 5s (customizable).
Note : this test does not need any expect()
but Karma will complain if you do a test without expect()
call. The test will succeed but will provoke a warning.
Upvotes: 0
Reputation: 8478
You should try this:
it('TC 3: should emit an event on change of checkbox', async(() => {
spyOn(component.checkboxEvent, 'emit');
spyOn(component, 'onChange');
const edlCheckbox = fixture.debugElement.query(By.css('checkbox ')).nativeElement;
edlCheckbox.click();
fixture.detectChanges();
expect(component.onChange).toHaveBeenCalled();
expect(component.checkboxEvent.emit).toHaveBeenCalledWith(true);
}));
Upvotes: 1