У меня есть простой угловой компонент, как показано ниже.
import { Component, Input, forwardRef, ViewEncapsulation } from "@angular/core";
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from "@angular/forms";
export const CUSTOM_CHECKBOX_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CheckBoxComponent),
multi: true
};
@Component({
selector: "checkbox",
templateUrl: "./checkBox.component.html",
styleUrls: ["./checkBox.component.scss"],
providers: [CUSTOM_CHECKBOX_CONTROL_VALUE_ACCESSOR],
encapsulation: ViewEncapsulation.None
})
export class CheckBoxComponent implements ControlValueAccessor {
@Input() name: string;
// Placeholders for the callbacks which are later provided
// by the Control Value Accessor
private innerValue: any = "";
private onTouchedCallback: () => void = () => { };
private onChangeCallback: (_: any) => void = () => { };
// get and set accessor----------------------
get value(): any {
return this.innerValue;
}
set value(v: any) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
// From ControlValueAccessor interfaces--------------
writeValue(value: any): void {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
registerOnChange(fn: any): void { this.onChangeCallback = fn; }
registerOnTouched(fn: any): void { this.onTouchedCallback = fn; }
}
Я пишу модульный тест для. Мой тест как ниже
import { CheckBoxComponent, CUSTOM_CHECKBOX_CONTROL_VALUE_ACCESSOR } from "./checkBox.component";
import { TestBed, async, ComponentFixture, fakeAsync, tick } from "@angular/core/testing";
import { DebugElement, Component } from "@angular/core";
import { By } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { CommonModule } from "@angular/common";
@Component({
selector: "tac-checkbox",
template: `<checkbox name="checkboxId1" label="Checkbox Label" [(ngModel)] = "checkValue" > `,
})
class CustomTestClass {
checkValue = false;
}
describe("Component: CheckBoxComponent", () => {
let component: CheckBoxComponent;
let fixture: ComponentFixture<CheckBoxComponent>;
let testComponent: CustomTestClass;
let testFixture: ComponentFixture<CustomTestClass>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [FormsModule, CommonModule],
declarations: [CheckBoxComponent, CustomTestClass],
providers: [CUSTOM_CHECKBOX_CONTROL_VALUE_ACCESSOR],
}).compileComponents().then(() => {
fixture = TestBed.createComponent(CheckBoxComponent);
component = fixture.componentInstance;
component.name = "checkbox";
});
}));
it("...", fakeAsync(() => {
testFixture = TestBed.createComponent(CustomTestClass);
testComponent = testFixture.componentInstance;
fixture.detectChanges();
const onChangeEvent = (change: any) => { console.log("There were changes ", change); };
const registerOnChangeMock = spyOn(component, "registerOnChange").and.callThrough();
const registerOnTouchedMock = spyOn(component, "registerOnTouched").and.callThrough();
const onMockWriteValue = spyOn(component, "writeValue").and.callThrough();
component.registerOnChange(onChangeEvent);
component.registerOnTouched(onChangeEvent);
testComponent.checkValue = !testComponent.checkValue;
fixture.detectChanges();
testFixture.detectChanges();
tick();
fixture.whenStable().then(() => {
expect(registerOnChangeMock).toHaveBeenCalledTimes(1); //pass
expect(registerOnTouchedMock).toHaveBeenCalledTimes(1);
//pass
expect(onMockWriteValue).toHaveBeenCalled(); //failed
expect(testComponent.checkValue).toEqual(component.value); //failed
});
}));
});
Из моего теста выше, я ожидаю, что component.value
будет равно testComponent.value
. Это не удалось, однако, мой вопрос заключается в том, что я изменил значение testComponent, разве контрольное значение также не должно обновляться? Также я ожидал, что writeValue
будет вызываться всякий раз, когда я меняю значение testComponent, однако это не так. Пожалуйста, что я делаю не так? Любая помощь будет оценена.