karma + jasmine & 스파이테스트

develop, jasmine, karma
written byzuhern1zuhern

in

2019. 02. 12


참조

자스민으로 프론트엔드 테스트 코드 작성하기
Vue 글로벌 컴포넌트 테스트
vue 공식: 단위 테스팅

스파이 테스트

  • 더미(dummy): 파라매터로 사용되며 전달만하고 실제 사용하지는 않는다.
  • 스텁(stub): 더미를 좀 더 구현하여 아직 개발하지 않은 메서드가 실제 작동하는 것처럼 보이게 만든 객체이다.
  • 스파이(spy): 스텁과 비슷하지만 내부적으로 기록을 남긴다는 점이 다르다. 특정 메서드가 호출되었는지 등의 상황을 감시(spying)한다.
  • 모의체(fake): 스텝에서 좀 더 발전하여 실제로 간단히 구현된 코드를 갖고 있지만, 운영 환경에서 사용할 수는 없는 객체다
  • 모형(mock): 더미, 스텁, 스파이를 혼합한 형태와 비슷하나 행위를 검증하는 용도로 주로 사용된다.

jasmin-ajax 설치 및 셋팅

  • 자스민에서는 ajax 테스트를 위한 jasmin-ajax 라이브러리를 제공한다

    npm i karma-jasmine-ajax --save-dev
  • karma.conf.js

    frameworks: ['jasmine-ajax', 'jasmine'],

예제 코드

// hello.js
var Hello = {
  getName(callback) {
    const req = new XMLHttpRequest();       // 가짜 request 생성
    req.open('GET', 'http://name', true);   // 가짜 request 셋팅
    req.onreadystatechange = function () {  // 가짜 request 호출 후 동작 셋팅
      if (req.readyState == 4) {
        if(req.status == 200) {
          callback(req.responseText);
        } else {
          callback("ajax error");
        }
      }
    }
    req.send(null);                         // 가짜 request 호출 !
    
    return 'World';
  }
}

테스트 코드

  • 테스트는 beforeEach -> it -> afterEach 순으로 실행
  • beforeEach: 테스트 케이스 실행 전에 테스트 환경 구성
  • afterEach: 테스트 케이스 종료 후 정리 작업에 사용하는 함수
// hello.spec.js
describe('Hello', ()=> {
  describe('getName함수는', ()=>{
    
    let request,
        response,
        callbackSpy;

    beforeEach(()=> {
      jasmine.Ajax.install();
      callbackSpy = jasmine.createSpy('callback');  // 스파이
      Hello.getName(callbackSpy);                   // 스파이 심기
      request = jasmine.Ajax.requests.mostRecent(); // Hello.getName의 Ajax request 결과 저장

      // 가짜 response
      response = {
        status: 200,
        responseText: 'Chris'
      };
      request.respondWith(response);                 // request랑 response 짝궁해줌
    });

    afterEach(()=> jasmine.Ajax.uninstall());

    it('HTTP 요청을 보낸다', () => {
      const expectUrl = 'http://name';
      expect(request.url).toBe(expectUrl);
    });

    it('콜백함수 파라매터로 이름을 반환한다', ()=> {
      expect(callbackSpy).toHaveBeenCalledWith(response.responseText);
    });
  });
});