Creating Test Case for Angular Service with Dependencies Using TestBed
Good Day.
Currently running a project in angular framework. I am attempting to write a test case for a service with dependencies, but obviously do not understand the how to scaffold it. Below are the two classes in question.
This is the LoginService
@Injectable({
providedIn: 'root'
})
export class LoginService implements CanActivate, OnInit {
constructor(private router: Router,
private httpClient: HttpClient,
private cookieService: CookieService) { }
This is the test class for LoginService:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginService} from './login.service';
import {HttpClient} from '@angular/common/http';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: CookieService;
let service: LoginService;
let fixture: ComponentFixture<LoginService>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LoginService],
providers: [Router, HttpClient, CookieService]
});
fixture = TestBed.createComponent(LoginService);
service = fixture.componentInstance;
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
});
it('should return true from isLoggedIn when token is set', function () {
spyOn(cookieService, 'get').and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
It is simple as I am trying it out. The error I am getting is :
Error: Unexpected value 'LoginService' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2547:1)
Basically my intention is to have the LoginService's dependencies injected and then use the spyOn method within the individual tests to disrupt flow as I deem fit.
A nudge in the right direction would be appreciated. If the solution is documented please do link.
Are services treated in a different way compared to the Components when using the TestBed? If I am honest I am not sure how to interpret the error as why would a Service have those annotations?
EDIT after reading @Dream88
The solution to my problem:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {LoginService} from './login.service';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from '../../app-routing.module';
import {TestBed} from '@angular/core/testing';
import {AppModule} from '../../app.module';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: jasmine.SpyObj<CookieService>;
let service: LoginService;
beforeEach(() => {
const cookieServiceSpy = jasmine.createSpyObj('CookieService', ['get']);
TestBed.configureTestingModule({
imports: [
AppModule,
AppRoutingModule,
HttpClientModule
],
providers: [LoginService, {
provide: CookieService, useValue: cookieServiceSpy
}]
});
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
service = new LoginService(router, httpClient, cookieService);
});
it('should return true from isLoggedIn when token is set', function () {
cookieService.get.and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
Long story short - I had no idea what I was typing. After understanding the underlying implementation it was straight forward. Thanks for the nudge. Marking Dream88 correct.
I asked my self how the prod code works. HHow are Services injected. What demarcates a service(@Injectable). That hinted to what should be in imported and providers.
Regards.
angular typescript testing karma-jasmine
add a comment |
Good Day.
Currently running a project in angular framework. I am attempting to write a test case for a service with dependencies, but obviously do not understand the how to scaffold it. Below are the two classes in question.
This is the LoginService
@Injectable({
providedIn: 'root'
})
export class LoginService implements CanActivate, OnInit {
constructor(private router: Router,
private httpClient: HttpClient,
private cookieService: CookieService) { }
This is the test class for LoginService:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginService} from './login.service';
import {HttpClient} from '@angular/common/http';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: CookieService;
let service: LoginService;
let fixture: ComponentFixture<LoginService>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LoginService],
providers: [Router, HttpClient, CookieService]
});
fixture = TestBed.createComponent(LoginService);
service = fixture.componentInstance;
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
});
it('should return true from isLoggedIn when token is set', function () {
spyOn(cookieService, 'get').and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
It is simple as I am trying it out. The error I am getting is :
Error: Unexpected value 'LoginService' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2547:1)
Basically my intention is to have the LoginService's dependencies injected and then use the spyOn method within the individual tests to disrupt flow as I deem fit.
A nudge in the right direction would be appreciated. If the solution is documented please do link.
Are services treated in a different way compared to the Components when using the TestBed? If I am honest I am not sure how to interpret the error as why would a Service have those annotations?
EDIT after reading @Dream88
The solution to my problem:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {LoginService} from './login.service';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from '../../app-routing.module';
import {TestBed} from '@angular/core/testing';
import {AppModule} from '../../app.module';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: jasmine.SpyObj<CookieService>;
let service: LoginService;
beforeEach(() => {
const cookieServiceSpy = jasmine.createSpyObj('CookieService', ['get']);
TestBed.configureTestingModule({
imports: [
AppModule,
AppRoutingModule,
HttpClientModule
],
providers: [LoginService, {
provide: CookieService, useValue: cookieServiceSpy
}]
});
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
service = new LoginService(router, httpClient, cookieService);
});
it('should return true from isLoggedIn when token is set', function () {
cookieService.get.and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
Long story short - I had no idea what I was typing. After understanding the underlying implementation it was straight forward. Thanks for the nudge. Marking Dream88 correct.
I asked my self how the prod code works. HHow are Services injected. What demarcates a service(@Injectable). That hinted to what should be in imported and providers.
Regards.
angular typescript testing karma-jasmine
add a comment |
Good Day.
Currently running a project in angular framework. I am attempting to write a test case for a service with dependencies, but obviously do not understand the how to scaffold it. Below are the two classes in question.
This is the LoginService
@Injectable({
providedIn: 'root'
})
export class LoginService implements CanActivate, OnInit {
constructor(private router: Router,
private httpClient: HttpClient,
private cookieService: CookieService) { }
This is the test class for LoginService:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginService} from './login.service';
import {HttpClient} from '@angular/common/http';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: CookieService;
let service: LoginService;
let fixture: ComponentFixture<LoginService>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LoginService],
providers: [Router, HttpClient, CookieService]
});
fixture = TestBed.createComponent(LoginService);
service = fixture.componentInstance;
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
});
it('should return true from isLoggedIn when token is set', function () {
spyOn(cookieService, 'get').and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
It is simple as I am trying it out. The error I am getting is :
Error: Unexpected value 'LoginService' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2547:1)
Basically my intention is to have the LoginService's dependencies injected and then use the spyOn method within the individual tests to disrupt flow as I deem fit.
A nudge in the right direction would be appreciated. If the solution is documented please do link.
Are services treated in a different way compared to the Components when using the TestBed? If I am honest I am not sure how to interpret the error as why would a Service have those annotations?
EDIT after reading @Dream88
The solution to my problem:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {LoginService} from './login.service';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from '../../app-routing.module';
import {TestBed} from '@angular/core/testing';
import {AppModule} from '../../app.module';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: jasmine.SpyObj<CookieService>;
let service: LoginService;
beforeEach(() => {
const cookieServiceSpy = jasmine.createSpyObj('CookieService', ['get']);
TestBed.configureTestingModule({
imports: [
AppModule,
AppRoutingModule,
HttpClientModule
],
providers: [LoginService, {
provide: CookieService, useValue: cookieServiceSpy
}]
});
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
service = new LoginService(router, httpClient, cookieService);
});
it('should return true from isLoggedIn when token is set', function () {
cookieService.get.and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
Long story short - I had no idea what I was typing. After understanding the underlying implementation it was straight forward. Thanks for the nudge. Marking Dream88 correct.
I asked my self how the prod code works. HHow are Services injected. What demarcates a service(@Injectable). That hinted to what should be in imported and providers.
Regards.
angular typescript testing karma-jasmine
Good Day.
Currently running a project in angular framework. I am attempting to write a test case for a service with dependencies, but obviously do not understand the how to scaffold it. Below are the two classes in question.
This is the LoginService
@Injectable({
providedIn: 'root'
})
export class LoginService implements CanActivate, OnInit {
constructor(private router: Router,
private httpClient: HttpClient,
private cookieService: CookieService) { }
This is the test class for LoginService:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginService} from './login.service';
import {HttpClient} from '@angular/common/http';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: CookieService;
let service: LoginService;
let fixture: ComponentFixture<LoginService>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [LoginService],
providers: [Router, HttpClient, CookieService]
});
fixture = TestBed.createComponent(LoginService);
service = fixture.componentInstance;
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
});
it('should return true from isLoggedIn when token is set', function () {
spyOn(cookieService, 'get').and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
It is simple as I am trying it out. The error I am getting is :
Error: Unexpected value 'LoginService' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2547:1)
Basically my intention is to have the LoginService's dependencies injected and then use the spyOn method within the individual tests to disrupt flow as I deem fit.
A nudge in the right direction would be appreciated. If the solution is documented please do link.
Are services treated in a different way compared to the Components when using the TestBed? If I am honest I am not sure how to interpret the error as why would a Service have those annotations?
EDIT after reading @Dream88
The solution to my problem:
import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {LoginService} from './login.service';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from '../../app-routing.module';
import {TestBed} from '@angular/core/testing';
import {AppModule} from '../../app.module';
describe('Service: LoginService', () => {
let router: Router;
let httpClient: HttpClient;
let cookieService: jasmine.SpyObj<CookieService>;
let service: LoginService;
beforeEach(() => {
const cookieServiceSpy = jasmine.createSpyObj('CookieService', ['get']);
TestBed.configureTestingModule({
imports: [
AppModule,
AppRoutingModule,
HttpClientModule
],
providers: [LoginService, {
provide: CookieService, useValue: cookieServiceSpy
}]
});
router = TestBed.get(Router);
httpClient = TestBed.get(HttpClient);
cookieService = TestBed.get(CookieService);
service = new LoginService(router, httpClient, cookieService);
});
it('should return true from isLoggedIn when token is set', function () {
cookieService.get.and.returnValue('true');
expect(service.isLoggedIn()).toBeTruthy();
});
});
Long story short - I had no idea what I was typing. After understanding the underlying implementation it was straight forward. Thanks for the nudge. Marking Dream88 correct.
I asked my self how the prod code works. HHow are Services injected. What demarcates a service(@Injectable). That hinted to what should be in imported and providers.
Regards.
angular typescript testing karma-jasmine
angular typescript testing karma-jasmine
edited Nov 22 '18 at 12:09
Nilo
asked Nov 22 '18 at 11:13
NiloNilo
134
134
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
This won't work as: fixture = TestBed.createComponent(LoginService); is supposed to create a component i.e something with annotation @component. With @service it is not meant to render a UI. Hence, the error.
Testing a service should be a case of simple testing functionality, no need for TestBed. You will only need to do this when you want to test a component which uses the said service, in which case you will need to add this to providers list.
For just testing Services, have a look on Angular Doc.
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429727%2fcreating-test-case-for-angular-service-with-dependencies-using-testbed%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This won't work as: fixture = TestBed.createComponent(LoginService); is supposed to create a component i.e something with annotation @component. With @service it is not meant to render a UI. Hence, the error.
Testing a service should be a case of simple testing functionality, no need for TestBed. You will only need to do this when you want to test a component which uses the said service, in which case you will need to add this to providers list.
For just testing Services, have a look on Angular Doc.
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
add a comment |
This won't work as: fixture = TestBed.createComponent(LoginService); is supposed to create a component i.e something with annotation @component. With @service it is not meant to render a UI. Hence, the error.
Testing a service should be a case of simple testing functionality, no need for TestBed. You will only need to do this when you want to test a component which uses the said service, in which case you will need to add this to providers list.
For just testing Services, have a look on Angular Doc.
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
add a comment |
This won't work as: fixture = TestBed.createComponent(LoginService); is supposed to create a component i.e something with annotation @component. With @service it is not meant to render a UI. Hence, the error.
Testing a service should be a case of simple testing functionality, no need for TestBed. You will only need to do this when you want to test a component which uses the said service, in which case you will need to add this to providers list.
For just testing Services, have a look on Angular Doc.
This won't work as: fixture = TestBed.createComponent(LoginService); is supposed to create a component i.e something with annotation @component. With @service it is not meant to render a UI. Hence, the error.
Testing a service should be a case of simple testing functionality, no need for TestBed. You will only need to do this when you want to test a component which uses the said service, in which case you will need to add this to providers list.
For just testing Services, have a look on Angular Doc.
answered Nov 22 '18 at 11:44
dream88dream88
1658
1658
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
add a comment |
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
Thank you for being patient with a newcomer. Have accepted your answer and edited my post with my solution. Please feel free to critique it should you feel.
– Nilo
Nov 22 '18 at 12:10
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53429727%2fcreating-test-case-for-angular-service-with-dependencies-using-testbed%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown