1

I tried to test service, http post, like this code below.

I follow this post for my testing, but I have a error.

My service code:

  public CreateProduct(newProd: Product): Observable<boolean> {
    .....
    let body = newProd.generateUrlencodedParameters(this.currentuser().token);
    return this.http.post(API.getUrl(Api.URLS.CreateProduct), body, {
      headers: headers
    })
      .map((response: Response) => {
        let res = response.json();

        if (res.StatusCode === 0) {
          return true;
        }
    }

My class Product:

export class Product{
    id: number;
    prod_number: String;
    prod_name: string;

    constructor(obj: any) {
        this.id= obj.id;
        this.prod_number= obj.prod_number;
        this.prod_name= obj.prod_name;
    }
    public generateUrlencodedParameters(token: string, id?: number): string 
   {
        let urlSearchParams = new URLSearchParams();
        urlSearchParams.append('prod_number', this.prod_number.toString());
        urlSearchParams.append('prod_name', this.prod_name.toString());
        urlSearchParams.append('token', token);
        return urlSearchParams.toString();
    }
}

I tried this code, to testing my service code:

describe('Create Product ', () => {
    let trackerFormService: ProductService,
      mockService = {
        createProduct: jasmine.createSpy('createProduct').and.returnValue(Observable.of('your session object mock goes here'))
      };
        beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [HttpModule],
          providers: [{
            provide: ProductService,
            useValue: mockService
          }] }); });

      beforeEach(inject([ProductService], (trackerFormService) => {
        service = trackerFormService;
      }));
      describe('createProduct', () => {
        it('add session ', () => {
          let fakeResponse = null;
          service.CreateProduct().subscribe((value) => {
            fakeResponse = value;
          }); }); });});

The result is:

ReferenceError: service is not defined

Please, can you suggest me any idea, how to solve this issue, or any example for testing service post.

Thnx.

site
  • 247
  • 5
  • 15

1 Answers1

0

One way to do it is to change your beforeEach function as follows:

    beforeEach(() => {
      TestBed.configureTestingModule({
          imports: [HttpModule],
          providers: [{
            provide: ProductService,
            useValue: mockService
          }] });
      service = TestBed.get(ProductService);
      });

Edit:

describe('Create Product ', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [HttpModule],
        providers: [{
          provide: ProductService,
          useValue: mockService
        }] });
    });
  it('add session ', inject([ProductService], (service: ProductService) => { 
        let fakeResponse = null;
        service.CreateProduct().subscribe((value) => {
          fakeResponse = value;
        });
      })
    });

Edit: You can use a fake for ProductService. But this would mean that you are not testing the ProductService. I am not sure what are you trying to test here.

You can try: (Notice the parameter passed)

    mockService = {
  createProduct: (newProduct) => jasmine.createSpy('createProduct').and.returnValue(Observable.of(false))
};

Or in a new file create the following class.

export class FakeProductService {
  public CreateProduct(newProd: Product): Observable<boolean> {
    return Observable.of(false);
  }
}

In your test file.

describe('Create Product ', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [HttpModule],
        providers: [{
          provide: ProductService,
          useClass: FakeProductService
        }] });
    });
  it('add session ', inject([ProductService], (service: ProductService) => { 
        let fakeResponse = null;
        service.CreateProduct(\*new Product()*\).subscribe((value) => {
          fakeResponse = value;
        });
      })
    });
Sameh Awad
  • 324
  • 2
  • 8
  • I tried like you say, but nothing happens. I think that the problem is for this service in `beforeEach(inject([ProductService], (trackerFormService) => { service = trackerFormService; }));` – site Jun 01 '18 at 10:44
  • remove the old beforeEach function as it is not needed anymore and move the one that you just created inside the describe function before the it function. – Sameh Awad Jun 01 '18 at 10:46
  • Expected 1 arguments, but got 0. in `service.CreateProduct()`, this because I have `public CreateProduct(newProd: Product): Observable {` – site Jun 01 '18 at 11:42
  • This has nothing to do with the test, now the service is declared and working. You need to fix what to pass for the methods. – Sameh Awad Jun 01 '18 at 11:49
  • Yes but show this error: TypeError: service.CreateProduct is not a function – site Jun 01 '18 at 11:51
  • If you don't want to test the createProduct function, then you can a class "FakeProductService" with the createProduct function taking one parameter and pass it in the provider using "useClass" instead of "useValue". It will return whatever value u put inside your fake class. – Sameh Awad Jun 01 '18 at 12:13
  • Thank you Sameh! I write you because I don't understand how to solve this issue. – site Jun 01 '18 at 12:18
  • `[ts] Type 'Observable' is not assignable to type Observable'. Type 'string' is not assignable to type 'boolean'.` in `return Observable.of('your session object mock goes here');` – site Jun 01 '18 at 13:00
  • so change it to boolean!! – Sameh Awad Jun 01 '18 at 13:02
  • Yes, I see, but really I don't understand, this testing. For example, what do you think for this: `(\*new Product()*\)`. Which is the best way to testing this service? – site Jun 01 '18 at 13:19
  • Add the mock variable that you want to pass to the service, or if you don't care about the variable then pass null instead of the comment. In any case what your are doing now is not testing the createProduct method, the code that copied from the other post and applied to your case actually bypasses the test and instead returns always the same result. To test this service and this function then you don't need to create a mock for it, instead pass it directly in the providers. `providers: [ProductService]` – Sameh Awad Jun 01 '18 at 13:24