본문으로 바로가기

TDD-Event

category JavaScript/Test 2020. 11. 30. 17:25

이벤트 테스트하기

처음에 만들기로 한 프로그램은 클릭했을 때 숫자가 올라가게 하는 것이었으니까

클릭 이벤트만 구현하면 되겠다

테스트 코드

클릭 이벤트는 어떻게 테스트 해야할까?

button 엘리멘트가 있어야할 것 같다

그럼 뷰에 데이터를 표시하기 위해 엘리먼트를 주입해서 데이터를 출력한 것과 비슷하게

clickCountView 모듈에 버튼 엘리먼트를 주입한 뒤에 거기에 클릭 이벤트를 구현하면 될 것 같다

clickCountView 모듈의 주입 구현은 beforeEach부분에 있으니 거기서 버튼 엘리먼트에 대한 의존성을 추가해보자

let clickCounter,updateElem,clickCountView,buttonElem;

beforeEach(()=>{
  clickCounter = App.ClickCounter();
  buttonElem = document.createElement('button');
  updateElem = document.createElement('span');
  clickCountView = App.ClickCountView(clickCounter, {updateElem, buttonElem});
});

나는 여기서 updateElem과 buttonElem을 객체로 묶어서 전달하는 것에 무릎을 탁 쳤다

함수로 전달되는 인자 갯수는 2개를 넘지 말라고 많이 듣긴 했지만 이런 경우에는 '어쩔 수 없지 뭐~'라는 생각을 가졌는데

저렇게 객체로 묶어서 전달하면 가독성도 헤치지않고 인자는 두개가 되니까

하나 배워갔다

이제 클릭 이벤트를 테스트하는 describe을 보자

describe('클릭 이벤트',()=>{
  it(('클릭 이벤트가 발생하면 increaseAndUpdateView가 실행'),()=>{
    spyOn(clickCountView,'increaseAndUpdateView');

    buttonElem.click();

    expect(clickCountView.increaseAndUpdateView).toHaveBeenCalled();

  });

});

buttonElem의 click이벤트가 실행되었을 때

clickCountView 모듈의 increaseAndUpdateView가 작동했는지 확인하는 테스트 코드

실제 코드

이전 까지는 updateElem만을 넘겨주었지만 이제부터 buttonElem이 묶인 객체로 넘겨주었기 때문에

options객체 안에서 엘리먼트들을 관리한다

App.ClickCountView = (clickCounter,options)=>{
    if(!clickCounter) throw Error('ClickCounter가 없습니다');
    if(!options.updateElem) throw Error('updateElem이 없습니다');

    options.buttonElem.addEventListener('click',()=>{
        increaseAndUpdateView();
    });

    return {
        updateView(){
            options.updateElem.innerHTML = clickCounter.getValue();
        },
        increaseAndUpdateView(){
            clickCounter.increase();
            this.updateView();
        }
    }
}

버튼 엘리먼트에 클릭 이벤트를 구현한 후에 increaseAndUpdateView 함수를 실행시키려고 했지만..

increaseAndUpdateView함수는 return에 구현되어있기 때문에 외부에서만 접근이 가능하고 내부인 그 위에선 현재 불러올 수가 없는 상태이다

App.ClickCountView = (clickCounter,options)=>{
    if(!clickCounter) throw Error('ClickCounter가 없습니다');
    if(!options.updateElem) throw Error('updateElem이 없습니다');

    const view = {
        updateView(){
            options.updateElem.innerHTML = clickCounter.getValue();
        },
        increaseAndUpdateView(){
            clickCounter.increase();
            this.updateView();
        }
    }

    options.buttonElem.addEventListener('click',()=>{
        view.increaseAndUpdateView();
    });

    return view;
}

여기서도 놀랐다..

리턴 하는 것도 객체니까 리턴할 객체 자체를 내부에 선언한 뒤에 객체 명만 리턴시켜주면 외부에서는 그대로 접근이 가능하고

내부에서도 view.increaseAndUpdateView를 호출하면 접근이 가능해진다

'JavaScript > Test' 카테고리의 다른 글

TDD-데이터 주입  (0) 2020.12.02
TDD-사용하기  (0) 2020.12.01
TDD-spyOn  (0) 2020.11.29
TDD-error  (0) 2020.11.27
TDD-view  (0) 2020.11.26