2

I have a simple service method that does an http post call to add a todoList:

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

I want to unit test this method and tried like this:

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

Why am I getting the following error?

Error: Expected one matching request for criteria "Match URL: https://localhost:44305/todolist", found none.

It is exactly the url that I am calling in the add method, why doesn't it find it?

Thanks in advance for your help

2
  • Please share your entire TestBed configuration and mocks/spies you may have defined. Commented Jul 30, 2020 at 6:55
  • 1
    hey @PhilippMeissner I've added the whole testclass :) Commented Jul 30, 2020 at 6:59

1 Answer 1

5

While all your mocks and imports are perfectly fine, you forgot to subscribe to the returned observable. This is important for the underlaying method to actually run. To make it work just subscribe to the stream and inside run your assertions.

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
    });
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

thanks, that helped a bit but the test still fails unfortunately. Now (with the subscribe and the done) I get these errors: Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL) Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL) at <Jasmine> Error: Expected no open requests, found 1: POST localhost:44305/todolist Shouldnt the httpMock.verify() make sure, that there are no open requests?
Ah, my bad. Updated my answer. It's been some time since I worked on this part of the tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.