I have a simple component with a button that toggles the visibility of a paragraph on and off. The button toggles the visibility correctly in the app, but it does not toggle properly in my Jasmine unit test (the content does not toggle properly). It also does not work properly if I manually click the toggle button in the test browser.
Interestingly, I also have a passing test that tests my toggle method that sets my hideContent
to false
. However, even with hideContent: false
, my content does not show up.
Relevant parts of my code:
alert-button-component.ts:
export class AlertButtonComponent implements OnInit {
hideContent = true;
constructor() { }
ngOnInit(): void {
}
toggle() {
this.hideContent = !this.hideContent;
}
}
alert-button.component.html:
<div class="content">
<p id="content" *ngIf="hideContent">My Content</p>
<button (click) = "toggle()" class="button">Toggle Visibility</button>
</div>
alert-button.component.spec.ts:
describe('AlertButtonComponent', () => {
let component: AlertButtonComponent;
let fixture: ComponentFixture<AlertButtonComponent>;
let de: DebugElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AlertButtonComponent ]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AlertButtonComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
fixture.detectChanges();
});
// Interestingly enough, this test works, but the content does not show up either
it('should toggle', () => {
expect(component.hideContent).toBeTruthy();
component.toggle();
expect(component.hideContent).toBeFalsy();
});
// returns TypeError: Cannot read property 'nativeElement' of null
it('should show content after clicking button', () => {
spyOn(component, 'toggle');
const el = de.nativeElement;
el.querySelector('button').dispatchEvent(new Event('click'));
expect(component.toggle).toHaveBeenCalled();
expect(de.query(By.css('#content')).nativeElement).toBeTruthy();
});
});
Any help would greatly be appreciated!
I have explained in the comments, it seems like you only need one line for both tests.
// Interestingly enough, this test works, but the content does not show up either
it('should toggle', () => {
expect(component.hideContent).toBeTruthy();
component.toggle();
fixture.detectChanges(); // to show the content, you have to call fixture.detectChanges()
// for change detection to kick in to see the content. This is optional, like you said the test
// already passses.
expect(component.hideContent).toBeFalsy();
});
// returns TypeError: Cannot read property 'nativeElement' of null
it('should show content after clicking button', () => {
spyOn(component, 'toggle');
const el = de.nativeElement;
el.querySelector('button').dispatchEvent(new Event('click'));
expect(component.toggle).toHaveBeenCalled();
fixture.detectChanges(); // again, call fixture.detectChanges for reason stated above.
// this time it is not optional
expect(de.query(By.css('#content')).nativeElement).toBeTruthy();
});
Edit
To debug your tests, I assume a browser opens when you're running npm run test
.
When the browser opens, quickly press F12 (or inspect the dom) and it should trip on the debugger points. Press play to release the debuggers I think there is even a debug button as well depending on what version of Karma you're running.
it('should show content after clicking button', () => {
spyOn(component, 'toggle');
const el = de.nativeElement;
el.querySelector('button').dispatchEvent(new Event('click'));
expect(component.toggle).toHaveBeenCalled();
debugger; // you shouldn't see the p tag
fixture.detectChanges(); // again, call fixture.detectChanges for reason stated above.
// this time it is not optional
expect(de.query(By.css('#content')).nativeElement).toBeTruthy();
debugger; // you should see the p tag, maybe even go through the DOM tree to see it
});
Another side note is that the first fixture.detectChanges
in the first beforeEach
calls ngOnInit
so it is needed. The other fixture.detectChanges
later on are what will change the view according to the change in state.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments