I am using the latest angular-cli with angular 2.1. The ponent test I want to write is simple: Get some data from a service and display it.
It works, when the data ist simply displayed in a paragraph, but it does not, when it is bound to a textarea.
Below is an excerpt from my template:
<p *ngIf="!isBusy" class="twain">
<i>{{settings.blockLoginMessage}}</i>
</p>
<textarea
id="blockLoginMessage"
name="blockLoginMessage"
[(ngModel)]="settings.blockLoginMessage"
class="form-control">
</textarea>
and the corresponding tests:
describe('SettingsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [SharedModule, TranslateModule.forRoot()],
declarations: [SettingsComponent],
providers: [
Overlay,
ToastsManager,
ViewContainerRef,
TranslateService,
SettingsService
]
});
fixture = TestBed.createComponent(SettingsComponent);
p = fixtureponentInstance;
settingsService = fixture.debugElement.injector.get(SettingsService);
getSettingsSpy = spyOn(settingsService, 'getSettings')
.and.returnValue(Observable.of(new Settings(true, false, 'test')).delay(500).toPromise());
setSettingsSpy = spyOn(settingsService, 'setSettings')
.and.returnValue(Observable.of(true).delay(500));
fixture.detectChanges();
});
it('should create the ponent', () => {
expect(p).toBeTruthy();
});
it('should show busy indicator as long as there are no settings', () => {
let busyPanel = fixture.debugElement.query(By.css('#busyPanel'));
expect(busyPanel).not.toBeNull('cant find busy');
});
it('should show loaded settings after observable finished (done)', done => {
fixture.detectChanges();
// get the spy promise and wait for it to resolve
getSettingsSpy.calls.mostRecent().returnValue.then(() => {
fixture.detectChanges();
let de = fixture.debugElement.query(By.css('.twain'));
let el = de.nativeElement;
expect(el.textContent).toBe('test', 'show loaded settings');
let de2 = fixture.debugElement.query(By.css('#blockLoginMessage'));
let el2: HTMLTextAreaElement = de2.nativeElement;
expect(el2.textContent).toBe('test', 'show loaded settings');
done();
});
});
});
Does anyone have a hint why this does not work?
Furthermore, my attempts with async
and fakeAsync
fail pletely, when I have a delay in my promises like above.
I am using the latest angular-cli with angular 2.1. The ponent test I want to write is simple: Get some data from a service and display it.
It works, when the data ist simply displayed in a paragraph, but it does not, when it is bound to a textarea.
Below is an excerpt from my template:
<p *ngIf="!isBusy" class="twain">
<i>{{settings.blockLoginMessage}}</i>
</p>
<textarea
id="blockLoginMessage"
name="blockLoginMessage"
[(ngModel)]="settings.blockLoginMessage"
class="form-control">
</textarea>
and the corresponding tests:
describe('SettingsComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [SharedModule, TranslateModule.forRoot()],
declarations: [SettingsComponent],
providers: [
Overlay,
ToastsManager,
ViewContainerRef,
TranslateService,
SettingsService
]
});
fixture = TestBed.createComponent(SettingsComponent);
p = fixture.ponentInstance;
settingsService = fixture.debugElement.injector.get(SettingsService);
getSettingsSpy = spyOn(settingsService, 'getSettings')
.and.returnValue(Observable.of(new Settings(true, false, 'test')).delay(500).toPromise());
setSettingsSpy = spyOn(settingsService, 'setSettings')
.and.returnValue(Observable.of(true).delay(500));
fixture.detectChanges();
});
it('should create the ponent', () => {
expect(p).toBeTruthy();
});
it('should show busy indicator as long as there are no settings', () => {
let busyPanel = fixture.debugElement.query(By.css('#busyPanel'));
expect(busyPanel).not.toBeNull('cant find busy');
});
it('should show loaded settings after observable finished (done)', done => {
fixture.detectChanges();
// get the spy promise and wait for it to resolve
getSettingsSpy.calls.mostRecent().returnValue.then(() => {
fixture.detectChanges();
let de = fixture.debugElement.query(By.css('.twain'));
let el = de.nativeElement;
expect(el.textContent).toBe('test', 'show loaded settings');
let de2 = fixture.debugElement.query(By.css('#blockLoginMessage'));
let el2: HTMLTextAreaElement = de2.nativeElement;
expect(el2.textContent).toBe('test', 'show loaded settings');
done();
});
});
});
Does anyone have a hint why this does not work?
Furthermore, my attempts with async
and fakeAsync
fail pletely, when I have a delay in my promises like above.
- fixture.isStable() returns false btw – Mattes83 Commented Oct 25, 2016 at 5:50
- Can you post a plete example, preferably just using a dummy ponent, and service, all posted in one page we can copy and paste and test as is. And please include only what is necessary to reproduce the problem (i.e. no translate module) or anything else that doesn't involve solving the problem of how to test ngModel. This is what an MVCE is – Paul Samsotha Commented Oct 25, 2016 at 6:12
- pls check Angular 2 Testing: Get Value from ngModel – Long De Commented Jul 13, 2017 at 7:16
1 Answer
Reset to default 8ngModel
updates asynchronously since RC5. You should test it asynchronous way:
it('should check initial value of ngModel', async(() => {
let fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
fixture.whenStable().then(() => {
let el = fixture.debugElement.query(By.css('select your input'));
let actual = selectElement.nativeElement.value;
expect(expected).toBe(actual);
});
}));