简体   繁体   English

Angular中的单元测试,测试组件未定义

[英]Unit Testing in Angular, Test Component is undefined

I am trying to unit test a "add object" (add dish) component in Angular 6. With my current code I get the error "Cannot read property 'dishForm' of undefined". 我正在尝试对Angular 6中的“添加对象”(添加菜肴)组件进行单元测试。使用我当前的代码,我收到错误消息“无法读取未定义的属性'dishForm'”。

So, it seems it does the DishAddComponent is not recognized as the component to be tested? 因此,似乎DishAddComponent未被识别为要测试的组件吗? Can anybody help me out with this? 有人可以帮我吗? Thanks in advance! 提前致谢!

I've also tried (amongst others) adding async to beforeEach, as described here: Angular 2 Testing - Component Instance is undefined , but it does not work. 我还尝试过(除其他方法外)将async添加到beforeEach,如下所述: Angular 2 Testing-Component Instance是undefined ,但它不起作用。

Angular Component to be Unit Tested: 要进行单元测试的角度组件:

export class DishAddComponent implements OnInit {
  public dishForm: FormGroup;

  constructor(private dishService: DishService,
    private formBuilder: FormBuilder,
    private router: Router) { }

  ngOnInit() {
    // define dishForm (with empty default values)
    this.dishForm = this.formBuilder.group({
      name: ['', [Validators.required, Validators.maxLength(30), Validators.pattern('[a-zA-Z :]*')]],
      country: [''],
      ingredients: this.formBuilder.array([]),
      recipe: ['', [Validators.required, Validators.minLength(50)]],
    }, { validator: CustomValidators.DishNameEqualsCountryValidator });
  }

  addIngredient(): void {
    let ingredientsFormArray = this.dishForm.get('ingredients') as FormArray;
    ingredientsFormArray.push(IngredientSingleComponent.createIngredient());
  }

  addDish(): void {
    if (this.dishForm.dirty && this.dishForm.valid) {

      let dish = this.dishForm.value;

      this.dishService.addDish(dish)
        .subscribe(
          () => {
            this.router.navigateByUrl('/dishes');
          });
    }
  }
}

Unit Test in Jest: 开玩笑的单元测试:

describe('DishAddComponent', () => {
  let component: DishAddComponent;
  let fixture: ComponentFixture<DishAddComponent>;
  let formGroup: FormGroup;
  let formBuilderMock: any;
  let dishServiceMock: any;

  beforeEach(() => {
      formBuilderMock = {
      group: jest.fn().mockName('formBuilderMock.group'),
      array: jest.fn().mockName('formBuilderMock.array')
    };

    dishServiceMock = {
      addDish: jest.fn().mockName('dishServiceMock.addDish')
    };

    TestBed.configureTestingModule({
      imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes(routes)],
      declarations: [ DishAddComponent, IngredientSingleComponent ],
      providers: 
      [ 
        { provide: FormBuilder, useValue: formBuilderMock },
        { provide: FormGroup, useValue: formGroup },
        { provide: DishService, useValue: dishServiceMock }
      ]
    });
    fixture = TestBed.createComponent(DishAddComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('form invalid when empty', () => {
    (console).log(component);
  expect(component.dishForm.valid).toBeFalsy();
 });
});

EDIT: If I use the code below, I get an error as well: 编辑:如果我使用下面的代码,我也会得到一个错误:

DishAddComponent › should create DishAddComponent›应该创建

expect(received).toBeTruthy() 期待(接受).toBeTruthy()

Received: undefined 收到:未定义

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

In the end I got rid of the "undefined error" with the code below. 最后,我用下面的代码摆脱了“未定义的错误”。 I needed to mock one of the childcomponents and create an instance of formbuilder. 我需要模拟一个子组件并创建一个formbuilder实例。 Thanks for the tips! 感谢您的提示!

describe('DishAddComponent', () => {
  let component: DishAddComponent;
  let fixture: ComponentFixture<DishAddComponent>;
  let dishServiceMock: any;

  // mock singleingredientcomponent
  @Component({
    selector: 'app-ingredient-single',
    template: '<div></div>',
  })
  class MockSingleIngredientComponent {
  @Input() public ingredientIndex: number;
  @Input() public ingredient: FormGroup;
  }

  // create new instance of FormBuilder
  const formBuilder: FormBuilder = new FormBuilder();

  beforeEach(async(() => {
    dishServiceMock = {
      addDish: jest.fn().mockName('dishServiceMock.addDish'),
      addIngredient: jest.fn().mockName('dishServiceMock.addIngredient')
    };

    TestBed.configureTestingModule({
      imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes([])],
      declarations: [ DishAddComponent, MockSingleIngredientComponent ],
      providers: 
      [ 
        { provide: FormBuilder, useValue: formBuilder },
        { provide: DishService, useValue: dishServiceMock }
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    // create component and test fixture
    fixture = TestBed.createComponent(DishAddComponent);

    // get test component from the fixture
    component = fixture.componentInstance;

    // ..
    fixture.detectChanges();
  });

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

Try to compile components by adding compileComponents() after configureTestingModule() 尝试通过在configureTestingModule()之后添加compileComponents()来编译组件

TestBed.configureTestingModule({
  imports: [ ReactiveFormsModule, FormsModule, RouterTestingModule.withRoutes(routes)],
  declarations: [ DishAddComponent, IngredientSingleComponent ],
  providers: 
  [ 
    { provide: FormBuilder, useValue: formBuilderMock },
    { provide: FormGroup, useValue: formGroup },
    { provide: DishService, useValue: dishServiceMock }
  ]
})
  .compileComponents();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM