Issue
In my Angular 8 project, on clicking on signout, a confirm window comes up and asks Yes/No to logout. I want to test whether the confirm window appears or not. In my spec.ts
, I wrote spyOn(window, 'confirm').and.returnValue(false);
. I don’t know whether that is correct or not. I need two things. Firstly, whether the confirm window comes up or not; and secondly, how to click on the ‘Yes’ option using jasmine. Please help. Below is my code:
header.component.ts
...
import { AuthenticationService } from '../../core/authentication.service';
...
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
legalName: any;
constructor(public authService: AuthenticationService, public accountService: AccountService, public router: Router) {}
ngOnInit() {
this.accountService.getTransactionHistory().subscribe((res) => {
res = JSON.parse(res);
this.legalName = res['Result'].array.RevTrxn[0].trxn.legalName;
})
}
signout() {
this.authService.signout();
}
authentication.service.ts
signout(){
var res = window.confirm("Are you Sure!")
if(res){
window.localStorage.removeItem('token');
this.router.navigate(['/login'])
}
}
header.component.spec.ts
import { HeaderComponent } from './header.component';
import { AuthenticationService } from 'src/app/core/authentication.service';
import { AccountService } from 'src/app/core/account.service';
import transactions from 'src/app/core/model/mock-transaction-history.json';
describe('HeaderComponent', () => {
let component: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>;
let debugElement: DebugElement;
let mockAuthService;
let mockAccountService;
let trans;
beforeEach(async(() => {
trans = transactions;
mockAccountService = jasmine.createSpyObj(['getTransactionHistory']);
mockAuthService = jasmine.createSpyObj(['signout']);
TestBed.configureTestingModule({
declarations: [HeaderComponent],
imports: [RouterTestingModule, HttpClientTestingModule],
providers: [
{ provide: AccountService, useValue: mockAccountService },
{ provide: AuthenticationService, useValue: mockAuthService },
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(HeaderComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
});
it('clicking on "Sign Out" should ask user to confirm', () => {
mockAccountService.getTransactionHistory.and.returnValue(of(JSON.stringify(trans)));
const callSignOut = mockAuthService.signout.and.returnValue([]);
spyOn(window, 'confirm').and.returnValue(false);
const signOut = debugElement.query(By.css('.sign-out'));
signOut.triggerEventHandler('click', {});
fixture.detectChanges();
expect(window.confirm).toHaveBeenCalled();
});
});
While running this, I am getting Expected spy confirm to have been called.
in karma console. I don’t know why it is not getting called. I have tested whether signout()
function of AuthenticationService
is getting called or not. It is getting called anyways. The window.confirm()
method is inside the signout()
function as you can see.
Solution
I’ll put my feedback as an answer rather than a comment, reason being, your way of doing unit testing is slightly misleading.
The idea of unit testing is to isolate each file (service, component, pipe etc) and then test its functionality. To isolate , we use use mocks. I can see that you have done it perfectly.
Now, as a part of unit testing you should test whether this.authService.signout();
is called on signout()
. Whether the authService.signout()
calls windows.confirm
should be a part of unit test of AuthenticationService
.
Coming to your question of testing window
object (for your service
which you should do), you need to create serviceWindowObj
and assign window
object to it. I have covered similar question where I replaced window
object. Take a look at it. I think you can get an idea from that.
Cheers !
Since you are new to unit testing of Angular, try this article which contains several more links at the bottom to help you out with best practices