Creating Test Case for Angular Service with Dependencies Using TestBed












0















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.










share|improve this question





























    0















    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.










    share|improve this question



























      0












      0








      0








      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.










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 12:09







      Nilo

















      asked Nov 22 '18 at 11:13









      NiloNilo

      134




      134
























          1 Answer
          1






          active

          oldest

          votes


















          0














          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.






          share|improve this answer
























          • 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











          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
          });


          }
          });














          draft saved

          draft discarded


















          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









          0














          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.






          share|improve this answer
























          • 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
















          0














          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.






          share|improve this answer
























          • 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














          0












          0








          0







          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.






          share|improve this answer













          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.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          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



















          • 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


















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Ottavio Pratesi

          Tricia Helfer

          15 giugno