Angular:测试 Http POST 方法

xer*_*him 2 unit-testing karma-jasmine angular angular-unit-test angular-test

我有一个简单的服务方法,可以调用http post添加 todoList:

add(event: any): Observable<TodoList> {
    let todoListToAdd: TodoList = { name: event.target.value, listItems: []};
    return this.http.post<TodoList>("https://localhost:44305/todolist", todoListToAdd);
}
Run Code Online (Sandbox Code Playgroud)

我想对这个方法进行单元测试并尝试如下:

import { TestBed, getTestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

import { TodolistService } from './todolist.service';
import { TodoList } from './todolist';
import { HttpResponse } from '@angular/common/http';

describe('TodolistService', () => {
  let injector: TestBed;
  let service: TodolistService;
  let httpMock: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule ],
      providers: [ TodolistService ]
    });

    injector = getTestBed();
    service = injector.get(TodolistService);
    httpMock = injector.get(HttpTestingController);
  });

  afterEach(() => {
    httpMock.verify();
  });

  describe('#getTodoLists', () => {
     it('getTodoLists - when called after add was called once, then it should return 3 todo lists', () => {
      const event = { target: { value: "test" } };
      const expectedTodoList: TodoList = { name: event.target.value, listItems: []};

      service.add(event);
  
      const req = httpMock.expectOne("https://localhost:44305/todolist");
      expect(req.request.method).toBe("POST");
      expect(req.request.body).toEqual(expectedTodoList);
      req.flush(expectedTodoList);
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

为什么我会收到以下错误?

错误:预期有一个针对条件“匹配 URL:https://localhost:44305/todolist”的匹配请求,但没有找到。

这正是我在 add 方法中调用的 url,为什么它找不到它?

在此先感谢您的帮助

Phi*_*ner 5

虽然您的所有模拟和导入都非常好,但您忘记了subscribe返回的可观察值。这对于底层方法的实际运行非常重要。为了使其仅适用subscribe于流并在内部运行您的断言。

import { TestBed, getTestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

import { TodolistService } from './todolist.service';
import { TodoList } from './todolist';
import { HttpResponse } from '@angular/common/http';

describe('TodolistService', () => {
  let injector: TestBed;
  let service: TodolistService;
  let httpMock: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule ],
      providers: [ TodolistService ]
    });

    injector = getTestBed();
    service = injector.get(TodolistService);
    httpMock = injector.get(HttpTestingController);
  });

  afterEach(() => {
    httpMock.verify();
  });

  describe('#getTodoLists', () => {
    it('getTodoLists - when called after add was called once, then it should return 3 todo lists', () => {
      const event = { target: { value: "test" } };
      const expectedTodoList: TodoList = { name: event.target.value, listItems: []};

      service.add(event).subscribe((todoList) => {
        expect(todoList).toEqual(expectedTodoList);
      });

      const req = httpMock.expectOne("https://localhost:44305/todolist");
      expect(req.request.method).toBe("POST");
      expect(req.request.body).toEqual(expectedTodoList);
      req.flush(expectedTodoList); // This will actually "run" the mocked request if there are any subscribers
    });
  });
});
Run Code Online (Sandbox Code Playgroud)