如何測試angular組件間傳值

前言

咱們知道angular組件間通信有多種方法,其中最經常使用的一種方法就是藉助於 @Input 和 @Output 進行通信。具體如何通信請參考angular組件間通信,本文再也不贅述,咱們來說講關於此方法如何進行單元測試。git

建立假組件

咱們單元測試父組件與子組件的的交互是否符合咱們的要求,咱們在父組件進行測試,就須要模擬一個假的子組件出來,這樣排除其餘因素對測試的影響。
好比如今我在分頁組件裏寫了一個每頁大小選擇組件,如今要測試一下組件間交互。如今分頁組件就是咱們的父組件,每頁大小組件就是咱們的子組件。咱們如今須要去模擬一個假的子組件出來。咱們先模擬一個假模塊出來。
咱們的子組件在core模塊裏,咱們在core模塊下創造一個core-testing模擬模塊。再在core-testing模塊下創造一個core組件,由於咱們是一個模擬模塊,咱們只須要ts文件便可。segmentfault

@Component({
  selector: 'app-size',
  template: `
    <p>
       size-select works!
    </p>
  `,
  styles: []
})
export class SizeComponent implements OnInit {
    constructor() {
    }

    ngOnInit() {
    }
}

爲了咱們能夠在父組件的測試文件中獲得模擬的子組件,咱們還須要一個controller,在core-testing文件夾下建立一個core-testing-controller.ts文件。CoreTestingController類繼承TestingControllerapp

export class CoreTestingController extends TestingController {
}

同時在咱們的core-testing.module裏聲明CoreTestingController爲提供者async

providers: [
    CoreTestingController
  ]

此時咱們的目錄樹ide

core-testing git:(134) ✗ tree   
.
├── core-testing-controller.ts
├── core-testing.module.ts
├── page
│   └── page.component.ts
└── size
    └── size.component.ts

由於咱們是模擬的子組件,因此咱們應該添加子組件的@Input 和 @Output,同時在構造函數裏把這個模擬的子組件添加到CoreTestingController裏。函數

export class SizeComponent implements OnInit {
  @Input() size: number;

  @Output() onChangeSize = new EventEmitter<number>();

  constructor(private controller: CoreTestingController) {
    this.controller.addUnit(this);
  }
}

此時咱們的準備工做就完成了。單元測試

單元測試

首先咱們引入假組件並聲明提供者測試

import {CoreTestingController} from '../core-testing/core-testing-controller';
import {SizeComponent} from '../core-testing/size/size.component';

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ PageComponent, SizeComponent ],
      imports: [FormsModule],
      providers: [
        CoreTestingController
      ]
    })
    .compileComponents();
  }));

我大家這裏引入的是咱們創造的假的SizeComponent,由於咱們父組件與子組件在同一個模塊裏,因此咱們直接引入SizeComponent就能夠。
此時咱們父組件想要子組件時就會使用假的子組件。
咱們先斷言@Input,咱們斷言父組件的值與咱們假的子組件值相等this

it('選擇每頁大小', () => {
    const controller = TestBed.get(CoreTestingController) as CoreTestingController;
    const sizeComponent = controller.get(SizeComponent) as SizeComponent;
    expect(sizeComponent.size).toBe(component.size);
  });

咱們這裏的get方法就對應的咱們以前的構造函數的addUnit方法,具體參考TestingController類定義的方法。
而後咱們再斷言子組件向父組件@Output也沒有問題,咱們先spyon父組件接收子組件值的方法,而後定義一個變量並傳給父組件,而後斷言父組件接收到的值與子組件傳的值相同。spa

spyOn(component, 'onSizeSelected');
const emitSize = 4;
sizeComponent.onChangeSize.emit(emitSize);
expect(component.onSizeSelected).toHaveBeenCalledWith(4);

這時咱們就達到了咱們測試的目的。
咱們啓動測試,發現咱們原本的選擇下拉框變成了文字,這就是咱們假的子組件的效果。
image.png

總結

咱們進行單元測試,就須要除被測組件外,其餘引用組件儘可能爲假,才能達到咱們的目的。

相關文章
相關標籤/搜索