Error this.http.post is not a function with Jasmine

huangapple go评论90阅读模式
英文:

Error this.http.post is not a function with Jasmine

问题

以下是您要翻译的部分:

I just started testing my software with Jasmine and Karma (haven't done any unit testing not E2E yet so I'm just a newbie here).

What I have been asked to do is to create a generic API service that you call every time you need to make an HTTP request, in order to avoid repeating code and making programming faster. I show you what I already have:

api.service.ts

  1. import { HttpClient, HttpContext, HttpParams } from '@angular/common/http'
  2. import { Injectable } from '@angular/core'
  3. import { Observable } from 'rxjs'
  4. @Injectable({
  5. providedIn: 'root'
  6. })
  7. export class ApiService {
  8. headers: ApiRequests = {
  9. httpHeaderAccept: 'application/json',
  10. context: new HttpContext(),
  11. params: new HttpParams()
  12. }
  13. constructor(private _http: HttpClient) {}
  14. post<T>(url: string, body: object): Observable<T> {
  15. return this._http.post<T>(url, body, { ...this.headers })
  16. }
  17. }

I do not show the rest of the HTTP methods because they are very similar, POST will do the trick here.

And now this is my .spec.ts file:

  1. import { HttpClient } from '@angular/common/http'
  2. import { TestBed } from '@angular/core/testing'
  3. import { of } from 'rxjs'
  4. import { ApiService } from './api.service'
  5. describe('ApiService', () => {
  6. let service: ApiService
  7. let httpClientSpyPost: {
  8. post: jasmine.Spy
  9. }
  10. beforeEach(() => {
  11. TestBed.configureTestingModule({
  12. providers: [
  13. ApiService,
  14. { provide: HttpClient, useValue: httpClientSpyPost }
  15. ]
  16. })
  17. service = TestBed.inject(ApiService)
  18. httpClientSpyPost = jasmine.createSpyObj('HttpClient', ['post'])
  19. })
  20. it('should be created', () => {
  21. expect(service).toBeTruthy()
  22. })
  23. it('(POST) -> should return a response with a body', (done: DoneFn) => {
  24. const body = {}
  25. const expectedResponse = {}
  26. httpClientSpyPost.post.and.returnValue(of(expectedResponse))
  27. service.post('url', body).subscribe((response) => {
  28. expect(response).toEqual(expectedResponse)
  29. done()
  30. })
  31. })
  32. })

And this is the error Jasmine is throwing me:

  1. TypeError: this._http.post is not a function

I don't really know what it does really mean and I think I've set up everything correct and tried some things I've read here.

英文:

I just started testing my software with Jasmine and Karma (haven't done any unit testing not E2E yet so I'm just a newbie here).

What I have been asked to do is to create a generic API service that you call everytime you need to make an HTTP request, in order to avoid repeating code and making programming faster. I show you what I already have:

api.service.ts

  1. import { HttpClient, HttpContext, HttpParams } from &#39;@angular/common/http&#39;
  2. import { Injectable } from &#39;@angular/core&#39;
  3. import { Observable } from &#39;rxjs&#39;
  4. @Injectable({
  5. providedIn: &#39;root&#39;
  6. })
  7. export class ApiService {
  8. headers: ApiRequests = {
  9. httpHeaderAccept: &#39;application/json&#39;,
  10. context: new HttpContext(),
  11. params: new HttpParams()
  12. }
  13. constructor(private _http: HttpClient) {}
  14. post&lt;T&gt;(url: string, body: object): Observable&lt;T&gt; {
  15. return this._http.post&lt;T&gt;(url, body, { ...this.headers })
  16. }
  17. }

I do not show the rest of the HTTP methods because they are very similar, POST will do the trick here.

And now this is my .spec.ts file:

  1. import { HttpClient } from &#39;@angular/common/http&#39;
  2. import { TestBed } from &#39;@angular/core/testing&#39;
  3. import { of } from &#39;rxjs&#39;
  4. import { ApiService } from &#39;./api.service&#39;
  5. describe(&#39;ApiService&#39;, () =&gt; {
  6. let service: ApiService
  7. let httpClientSpyPost: {
  8. post: jasmine.Spy
  9. }
  10. beforeEach(() =&gt; {
  11. TestBed.configureTestingModule({
  12. providers: [
  13. ApiService,
  14. { provide: HttpClient, useValue: httpClientSpyPost }
  15. ]
  16. })
  17. service = TestBed.inject(ApiService)
  18. httpClientSpyPost = jasmine.createSpyObj(&#39;HttpClient&#39;, [&#39;post&#39;])
  19. })
  20. it(&#39;should be created&#39;, () =&gt; {
  21. expect(service).toBeTruthy()
  22. })
  23. it(&#39;(POST) -&gt; should return a response with a body&#39;, (done: DoneFn) =&gt; {
  24. const body = {}
  25. const expectedResponse = {}
  26. httpClientSpyPost.post.and.returnValue(of(expectedResponse))
  27. service.post(&#39;url&#39;, body).subscribe((response) =&gt; {
  28. expect(response).toEqual(expectedResponse)
  29. done()
  30. })
  31. })
  32. })

And this is the error Jasmine is throwing me:

  1. TypeError: this._http.post is not a function

I don't really know what it does really mean and I think I've set up everything correct and tried some things I've read here.

答案1

得分: 1

  1. import { HttpClient } from '@angular/common/http'
  2. import { TestBed } from '@angular/core/testing'
  3. import { of } from 'rxjs'
  4. import { ApiService } from './api.service'
  5. describe('ApiService', () => {
  6. let service: ApiService
  7. let httpClientSpyPost: {
  8. post: jasmine.Spy
  9. }
  10. beforeEach(() => {
  11. httpClientSpyPost = jasmine.createSpyObj('HttpClient', ['post'])
  12. TestBed.configureTestingModule({
  13. providers: [
  14. ApiService,
  15. { provide: HttpClient, useValue: httpClientSpyPost }
  16. ]
  17. })
  18. service = TestBed.inject(ApiService)
  19. })
  20. it('should be created', () => {
  21. expect(service).toBeTruthy()
  22. })
  23. it('(POST) -> should return a response with a body', (done: DoneFn) => {
  24. const body = {}
  25. const expectedResponse = {}
  26. httpClientSpyPost.post.and.returnValue(of(expectedResponse))
  27. service.post('url', body).subscribe((response) => {
  28. expect(response).toEqual(expectedResponse)
  29. done()
  30. })
  31. })
  32. })

这是您提供的代码的翻译部分。

英文:
  1. import { HttpClient } from &#39;@angular/common/http&#39;
  2. import { TestBed } from &#39;@angular/core/testing&#39;
  3. import { of } from &#39;rxjs&#39;
  4. import { ApiService } from &#39;./api.service&#39;
  5. describe(&#39;ApiService&#39;, () =&gt; {
  6. let service: ApiService
  7. let httpClientSpyPost: {
  8. post: jasmine.Spy
  9. }
  10. beforeEach(() =&gt; {
  11. httpClientSpyPost = jasmine.createSpyObj(&#39;HttpClient&#39;, [&#39;post&#39;])
  12. TestBed.configureTestingModule({
  13. providers: [
  14. ApiService,
  15. { provide: HttpClient, useValue: httpClientSpyPost }
  16. ]
  17. })
  18. service = TestBed.inject(ApiService)
  19. })
  20. it(&#39;should be created&#39;, () =&gt; {
  21. expect(service).toBeTruthy()
  22. })
  23. it(&#39;(POST) -&gt; should return a response with a body&#39;, (done: DoneFn) =&gt; {
  24. const body = {}
  25. const expectedResponse = {}
  26. httpClientSpyPost.post.and.returnValue(of(expectedResponse))
  27. service.post(&#39;url&#39;, body).subscribe((response) =&gt; {
  28. expect(response).toEqual(expectedResponse)
  29. done()
  30. })
  31. })
  32. })

Try assign httpClientSpyPost before TestBed being configured. It looks like you passing undefined value and later on your assign don't have effect.

答案2

得分: 1

Probably due to the service being created with the initialized spy object injected into it.

Initialize the spy object before the service = line or even safer before the call to configureTestModule:

  1. httpClientSpyPost = jasmine.createSpyObj('HttpClient', ['post'])
  2. TestBed.configureTestingModule(
  3. ...
英文:

Probably due to the service being created with the initialized spy object injected into it.

Initialize the spy object before the service = line or even safer before the call to configureTestModule:

  1. httpClientSpyPost = jasmine.createSpyObj(&#39;HttpClient&#39;, [&#39;post&#39;])
  2. TestBed.configureTestingModule(
  3. ...

huangapple
  • 本文由 发表于 2023年2月24日 16:07:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75554006.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定