【问题标题】:Angular FormControl Jest test causing TypeError: Converting circular structure to JSONAngular FormControl Jest 测试导致 TypeError:将循环结构转换为 JSON
【发布时间】:2020-12-02 04:58:54
【问题描述】:

在 Angular 项目中使用 Jest 运行测试时出现以下错误。

UnhandledPromiseRejectionWarning: TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'       
    |     property 'element' -> object with constructor 'Object'
    |     property 'publicProviders' -> object with constructor 'Object'
    |     property 'ɵNgNoValidate_65' -> object with constructor 'Object'
    --- property 'parent' closes the circle

我已经拆开来找出导致错误的原因,很明显它是由组件中的表单引起的。如果我从 FormGroup 中删除实际的 FormControls(表单域),那么测试运行没有问题。其他几种形式也是如此,我试过了。

我了解错误的含义,但不了解 FormControl 中导致该错误的原因。什么可能导致此错误?

@Component({
  selector: 'app-edit-title-form',
  template: `
<form (ngSubmit)="onSubmit()" [formGroup]="form" novalidate>
    <input type="text" formControlName="title"> <!-- If this is removed then tests run -->
</form>
`
})
export class EditTitleFormComponent implements OnInit {
  @Input() title: string = '';
  @Output() onSave: EventEmitter<string> = new EventEmitter();

  public form!: FormGroup;

  constructor(private formBuilder: FormBuilder) {}

  ngOnInit(): void {
    this.initForm();
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (changes.title.currentValue) {
      this.form.controls.title.setValue(changes.title.currentValue);
      this.form.markAsPristine();
    }
  }

  get field() {
    return this.form.controls;
  }

  public onSubmit(): void {
    this.onSave.emit(title);
  }

  private initForm(): void {
    this.form = this.formBuilder.group({
      title: [this.title, []], // If this line is removed along with the html input field, then tests run 
    });
  }
}
describe('EditTitleFormComponent', () => {
  let component: EditTitleFormComponent;
  let fixture: ComponentFixture<EditTitleFormComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        ReactiveFormsModule,
      ],
      declarations: [
        EditTitleFormComponent,
      ],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(EditTitleFormComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

【问题讨论】:

  • 最近安装 npm 后,我遇到了同样的错误。您正在运行什么版本的 jest 和 jest-preset-angular?我在安装之前没有这个问题。
  • 我们能够通过将 jest 更新为 26.1.0 并将 jest-preset-angular 更新为 8.2.1 来解决此问题。希望对您有所帮助!
  • 我在使用 mat-table 测试组件时遇到了类似的错误。我更新到 @angular/common@10.0.10 (和其他相关包),之后它工作了。
  • 这个@nicolaib 有什么更新吗?
  • 尝试了上述所有解决方案,但对我不起作用。我正在运行 jest 版本 26.6.3、jest-preset-angular 版本 8.3.、@types/jest 版本 ^26.0.15 和 angular-common 版本 10.2.3

标签: angular jestjs


【解决方案1】:

我遇到了类似的东西,看起来也与 FormControls 相关。我通过将 NoopAnimationsModule 添加到我的 TestBed.configureTestingModule() 解决了这个问题。这可能不是您需要导入的确切模块,但它让我克服了这个错误。您一定要确保在您的测试中考虑了所有构造函数注入。

除了确保提供所有可注入程序之外,您还需要确保所有服务模拟都已到位。例如,当我忽略了将等效项添加到下面的“fetchthings: jest.fn()”模拟中时,我再次遇到了这个错误:

{ provide: MyService, useValue: { fetchThings: jest.fn() } }

【讨论】:

    【解决方案2】:

    可能不是您的情况的答案,但在我的情况下,我有一个 Object.keys().flatMap(...) 在来自路由解析器的东西上运行,但在我的测试中没有处理,因此它有效地运行 Object.keys(undefined).flatMap(...)。这似乎让 jest 不高兴,得到了类似的转换循环结构错误,所以我确保 Object.keys 调用总是有一个值,jest 又高兴了。

    【讨论】:

      【解决方案3】:

      尝试在您的组件构造函数参数上使用@Optional

      constructor(@Optional private formBuilder: FormBuilder) {}
      

      我的类似错误首先是在我们的自定义库测试中由注入的ActivatedRoute 引起的。通过在TestBed 中导入RouterTestingModule 解决了这个问题。

       beforeEach(
          waitForAsync(() => {
            TestBed.configureTestingModule({
              imports: [RouterTestingModule, ReactiveFormsModule],
              declarations: [RadioComponent, TestComponent, FieldsetComponent, ErrorMessageComponent],
            }).compileComponents();
          })
        );
      

      然后,库测试运行良好,但应用程序测试显示相同的错误,通过将 @Optional 放入自定义库组件构造函数参数中得到解决。

      更新

      此错误似乎在各种情况下都会发生。我最近的是插入一个未定义的{{data.something}} 的属性。用{{data?.something}} 修复。这只是一个例子。

      关键是这个错误隐藏了真正的原因。当我找到解决方法时,我会更新。

      【讨论】:

        【解决方案4】:

        我在对所有测试套件运行 jest 时遇到了这个问题,因此它会从项目中提取每个 spec.ts。

        尝试对挂在“未处理的承诺拒绝”上的单个特定文件运行 jest,它将输出该文件的确切问题。它基本上可以是任何东西(对我来说,它在 spec.ts 中缺少导入,有时缺少属性值分配,等等)。

        【讨论】:

          猜你喜欢
          • 2019-01-05
          • 2020-08-18
          • 2021-01-01
          • 1970-01-01
          • 2016-01-22
          • 2018-10-05
          • 2016-01-22
          • 2017-06-29
          • 1970-01-01
          相关资源
          最近更新 更多