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

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

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

import { HttpClient, HttpContext, HttpParams } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { Observable } from 'rxjs'

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  headers: ApiRequests = {
    httpHeaderAccept: 'application/json',
    context: new HttpContext(),
    params: new HttpParams()
  }

  constructor(private _http: HttpClient) {}

  post<T>(url: string, body: object): Observable<T> {
    return this._http.post<T>(url, body, { ...this.headers })
  }
}

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:

import { HttpClient } from '@angular/common/http'
import { TestBed } from '@angular/core/testing'
import { of } from 'rxjs'
import { ApiService } from './api.service'

describe('ApiService', () => {
  let service: ApiService
  let httpClientSpyPost: {
    post: jasmine.Spy
  }

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        ApiService,
        { provide: HttpClient, useValue: httpClientSpyPost }
      ]
    })
    service = TestBed.inject(ApiService)
    httpClientSpyPost = jasmine.createSpyObj('HttpClient', ['post'])
  })

  it('should be created', () => {
    expect(service).toBeTruthy()
  })

  it('(POST) -> should return a response with a body', (done: DoneFn) => {
    const body = {}
    const expectedResponse = {}
    httpClientSpyPost.post.and.returnValue(of(expectedResponse))
    service.post('url', body).subscribe((response) => {
      expect(response).toEqual(expectedResponse)
      done()
    })
  })
})

And this is the error Jasmine is throwing me:

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

import { HttpClient, HttpContext, HttpParams } from &#39;@angular/common/http&#39;
import { Injectable } from &#39;@angular/core&#39;
import { Observable } from &#39;rxjs&#39;

@Injectable({
  providedIn: &#39;root&#39;
})
export class ApiService {
  headers: ApiRequests = {
    httpHeaderAccept: &#39;application/json&#39;,
    context: new HttpContext(),
    params: new HttpParams()
  }

  constructor(private _http: HttpClient) {}

  post&lt;T&gt;(url: string, body: object): Observable&lt;T&gt; {
    return this._http.post&lt;T&gt;(url, body, { ...this.headers })
  }
}

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:

import { HttpClient } from &#39;@angular/common/http&#39;
import { TestBed } from &#39;@angular/core/testing&#39;
import { of } from &#39;rxjs&#39;
import { ApiService } from &#39;./api.service&#39;

describe(&#39;ApiService&#39;, () =&gt; {
  let service: ApiService
  let httpClientSpyPost: {
    post: jasmine.Spy
  }

  beforeEach(() =&gt; {
    TestBed.configureTestingModule({
      providers: [
        ApiService,
        { provide: HttpClient, useValue: httpClientSpyPost }
      ]
    })
    service = TestBed.inject(ApiService)
    httpClientSpyPost = jasmine.createSpyObj(&#39;HttpClient&#39;, [&#39;post&#39;])
  })

  it(&#39;should be created&#39;, () =&gt; {
    expect(service).toBeTruthy()
  })

  it(&#39;(POST) -&gt; should return a response with a body&#39;, (done: DoneFn) =&gt; {
    const body = {}
    const expectedResponse = {}
    httpClientSpyPost.post.and.returnValue(of(expectedResponse))
    service.post(&#39;url&#39;, body).subscribe((response) =&gt; {
      expect(response).toEqual(expectedResponse)
      done()
    })
  })
})

And this is the error Jasmine is throwing me:

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

import { HttpClient } from '@angular/common/http'
import { TestBed } from '@angular/core/testing'
import { of } from 'rxjs'
import { ApiService } from './api.service'

describe('ApiService', () => {
  let service: ApiService
  let httpClientSpyPost: {
    post: jasmine.Spy
  }

  beforeEach(() => {
    httpClientSpyPost = jasmine.createSpyObj('HttpClient', ['post'])

    TestBed.configureTestingModule({
      providers: [
        ApiService,
        { provide: HttpClient, useValue: httpClientSpyPost }
      ]
    })
    service = TestBed.inject(ApiService)
  })

  it('should be created', () => {
    expect(service).toBeTruthy()
  })

  it('(POST) -> should return a response with a body', (done: DoneFn) => {
    const body = {}
    const expectedResponse = {}
    httpClientSpyPost.post.and.returnValue(of(expectedResponse))
    service.post('url', body).subscribe((response) => {
      expect(response).toEqual(expectedResponse)
      done()
    })
  })
})

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

英文:
import { HttpClient } from &#39;@angular/common/http&#39;
import { TestBed } from &#39;@angular/core/testing&#39;
import { of } from &#39;rxjs&#39;
import { ApiService } from &#39;./api.service&#39;

describe(&#39;ApiService&#39;, () =&gt; {
  let service: ApiService
  let httpClientSpyPost: {
    post: jasmine.Spy
  }

  beforeEach(() =&gt; {
    httpClientSpyPost = jasmine.createSpyObj(&#39;HttpClient&#39;, [&#39;post&#39;])

    TestBed.configureTestingModule({
      providers: [
        ApiService,
        { provide: HttpClient, useValue: httpClientSpyPost }
      ]
    })
    service = TestBed.inject(ApiService)
  })

  it(&#39;should be created&#39;, () =&gt; {
    expect(service).toBeTruthy()
  })

  it(&#39;(POST) -&gt; should return a response with a body&#39;, (done: DoneFn) =&gt; {
    const body = {}
    const expectedResponse = {}
    httpClientSpyPost.post.and.returnValue(of(expectedResponse))
    service.post(&#39;url&#39;, body).subscribe((response) =&gt; {
      expect(response).toEqual(expectedResponse)
      done()
    })
  })
})

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:

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

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:

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

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:

确定