angular - 在 Angular 中,spyOn 无法使用异步管道

标签 angular typescript jasmine

我有一个运行良好的简单组件,如下所示:

@Component({
  selector: 'component',
  template: `
    {{userWithAsyncPipe | async | json}} <!-- = null in test -->
    {{userFromOnInit | json}} <!-- working test -->
  `,
})
export class Component implements OnInit {
  constructor(private service: MyService) {
  }

  userWithAsyncPipe = this.service.getUser();
  userFromOnInit;

  ngOnInit() {
    this.service.getUser().subscribe(user => this.userFromOnInit = user);
  }
}

我试图通过模拟 service.getUser() 方法来测试它。所以我编写了一个大约如下所示的测试组件:

describe('', () => {

  ...
  let myService;
  beforeEach(() => {
    myService = TestBed.inject(MyService);
  });

  it('', () => {
    spyOn(myService, 'getUser').and.returnValue(of({name: 'Jacob'}));
  });
});

但是当我查看 karma 浏览器时,只有变量 userFromOnInit 被解析。 userWithAsyncPipe 等于 null

那是什么鬼?

最佳答案

这里有一个例子 ng-mocks

https://codesandbox.io/s/gallant-bas-is5zy?file=/src/test.spec.ts

import { CommonModule } from "@angular/common";
import {
  Component,
  EventEmitter,
  Input,
  NgModule,
  Injectable,
  Output
} from "@angular/core";
import { MockBuilder, MockInstance, MockRender, ngMocks } from "ng-mocks";
import { EMPTY, Observable, of } from "rxjs";

@Injectable()
class MyService {
  getUser(): Observable<any> {
    return EMPTY;
  }
}

@Component({
  selector: "app-target",
  template: `
    {{ userWithAsyncPipeFn() | async | json }}
    {{ userWithAsyncPipe | async | json }}
    {{ userFromOnInit | json }}
  `
})
class TargetComponent {
  userWithAsyncPipeFn = () => this.service.getUser();
  userWithAsyncPipe = this.service.getUser();
  userFromOnInit: any;

  constructor(private service: MyService) {}

  ngOnInit() {
    this.service.getUser().subscribe((user) => (this.userFromOnInit = user));
  }
}

@NgModule({
  imports: [CommonModule],
  declarations: [TargetComponent],
  providers: [MyService]
})
class TargetModule {}
describe("my sandbox", () => {
  beforeEach(() => MockBuilder(TargetComponent, TargetModule));

  it("should do something", () => {
    MockInstance(MyService, "getUser", () => of({ name: "Jacob" }));

    const fixture = MockRender(TargetComponent);
    expect(fixture.nativeElement.innerHTML.match(
      /\{\s*"name":\s*"Jacob"\s*\}/g
    ).length).toEqual(3);
  });
});

关于angular - 在 Angular 中,spyOn 无法使用异步管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66126147/

相关文章:

angular - 如何测试 Angular Service Worker

javascript - 与常规可观察对象相比,Angular HTTP 可观察对象的行为有所不同?

Angular 6 尝试比较 '[object Object]' 时出错。仅允许数组和可迭代对象

刷新页面时angular2 rc1默认路由问题

javascript - 我如何解决 'Property ' 宽度'在类型 'HTMLElement' 上不存在。'在 vscode 中使用//@ts-check 类型检查 Javascript(不是 Typescript)时?

使用transformrequest时,JavaScript组件没有名为 "available"的方法

javascript - Angular2 阻止在指令中按下回车键时提交表单

javascript - map 方法中的散布算子复制对象时的使用方法

unit-testing - Jasmine 使用 templateUrl 测试 AngularJS 指令

angularjs - 如何在 Protractor 中使用 Jasmine 和 CucumberJS