首页 > 解决方案 > Angular 测试不调用期望导致“规范没有期望”

问题描述

我有一个对我的后端进行 HTTP 调用的服务,我正在尝试测试它是否会得到用户的响应,在运行测试时我得到了一个Spec has no expectation,即使我在订阅中有一个。所有这些测试都通过了,但 2 的输出为SPEC HAS NO EXPECTATION

这是我的代码:

describe('Auth Service Testing', () => {
  let httpClientSpy: { get: jasmine.Spy };
  let authServ: AuthService;
  let authAct: AuthActions;
  let userAct: UserActions;
  let checkoutAct: CheckoutActions;
  let productAct: ProductActions;
  let store: Store<any>;
  let localStorageServ: LocalStorageService;
  let authResponse;
  const expectedUserResponse = {
    users: [],
    count: 25,
    current_page: 1,
    pages: 2
  };

  beforeEach(() => {
    httpClientSpy = jasmine.createSpyObj('HttpClient', ['get']);
    authServ = new AuthService(
      <any>httpClientSpy,
      authAct,
      userAct,
      checkoutAct,
      productAct,
      store,
      localStorageServ
    );
  });

  it('should get users response', () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    authServ.authorized().subscribe((users) => {
      authResponse = users;
      expect(users).toEqual(jasmine.objectContaining({ users: [] }));
    });

  });

  it('should equal to expected users response', () => {
    expect(authResponse).toEqual(expectedUserResponse);
  });

  it('should return null if theres an error', () => {
    httpClientSpy.get.and.returnValue(asyncError(expectedUserResponse));
    authServ
      .authorized()
      .subscribe(() => {}, (error) => expect(error).toBe(null));
  });
});

另外,我遵循了 angular HTTP testing guide angular test 我想知道这是一个错误还是其他什么。

业力结果:

Auth Service Testing
SPEC HAS NO EXPECTATIONS should return null if there's an error
SPEC HAS NO EXPECTATIONS should get users response
should equal to expected users response

更新

缺少的代码是expect(httpClientSpy.get.calls.count()).toBe(1);这很奇怪,我认为这个调用发出了一个 http get 请求httpClientSpy.get.and.returnValue(asyncError(expectedUserResponse));

但是在指南的错误测试中,他们没有这个。有人可以阐明这一点吗?

来自朝鲜的很多爱。<3

标签: angularkarma-jasmineangular-test

解决方案


使用订阅对 observable 进行单元测试真的很困难。单元测试将通过但应该失败的许多极端情况。即使您将done()回调与finiazlier 或错误处理程序一起使用。

每当一个 observable 只发出一个预期的结果时,你就应该使用一个 Promise 来代替。

  it('should get users response', async () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    const users = await = authServ.authorized().toPromise();

    expect(users).toEqual(jasmine.objectContaining({ users: [] }));
  });

每当 observable 发出多个值时,您都可以转换为数组并仍然使用 Promise。

  it('should get users response', async () => {
    httpClientSpy.get.and.returnValue(asyncData(expectedUserResponse));

    const users = await = authServ.authorized().pipe(
        toArray()
    ).toPromise();

    expect(users).toEqual(jasmine.objectContaining([{ users: [] }]));
  });

的优点toPromise()是它总是解决。即使 observable 没有发出任何值,并且如果在 observable 中抛出任何未捕获的错误,它也会导致单元测试失败。


推荐阅读