Jasmine을 사용하여 객체가없는 함수를 감시


154

나는 Jasmine을 처음 사용하고 방금 사용하기 시작했습니다. 객체와 관련이없는 많은 함수가있는 라이브러리 js 파일이 있습니다 (예 : 전역 적). 이 기능들을 감시하려면 어떻게해야합니까?

창 / 문서를 개체로 사용하려고 시도했지만 함수가 호출되었지만 스파이가 작동하지 않았습니다. 또한 다음과 같이 가짜 객체로 감싸려고 시도했습니다.

var fakeElement = {};
fakeElement.fakeMethod = myFunctionName;
spyOn(fakeElement, "fakeMethod");

와 테스트

expect(fakeElement.fakeMethod).toHaveBeenCalled();

스파이가 작동하지 않았기 때문에 이것은 작동하지 않습니다

답변:


155

함수를 정의하는 경우 :

function test() {};

그러면 다음과 같습니다.

window.test = function() {}  /* (in the browser) */

그래서 spyOn(window, 'test')작동합니다.

그렇지 않은 경우 다음을 수행 할 수도 있습니다.

test = jasmine.createSpy();

작동하지 않는 설정이 있으면 다른 설정이 진행중인 것입니다.

나는 당신의 fakeElement기술이 무대 뒤에서 일어나고 있기 때문에 효과 가 없다고 생각합니다 . 원래 globalMethod는 여전히 동일한 코드를 가리 킵니다. 스파이가하는 것은 프록시이지만 객체의 컨텍스트에서만 가능합니다. 테스트 코드가 fakeElement를 통해 호출되도록 할 수 있다면 작동하지만 전역 fns를 포기할 수 있습니다.


2
효과가 있었다! 필자가 이전에 만든 오류는 메서드 대신 method ()를 사용하여 spyOn을 호출하는 것입니다. 감사!
Chetter Hummin

3
'window'가 지정되지 않아 자동화의 일부로 테스트를 실행하기 위해 chutzpah를 사용하는 spyOn (window, 'test')을 사용하는 데 문제가 있습니다. jasmine.createSpy ()를 사용하면이 문제를 해결할 수 있습니다.
Henners 2009 년

7
jasmine.createSpy ()가 완벽하게 작동했습니다. 감사!
dplass

1
test = jasmine.createSpy();angularJ를 감시하는 데 $anchroScroll완벽하게 작동했습니다
Edgar Martinez

1
어떤 이유로 든 작동 할 수 없지만 기존 창 기능을 조롱하려고하기 때문일 수도 있습니다. $window.open(url, '_blank');새 탭 (또는 브라우저 설정에 따라 창)을 열어야합니다. 이 함수를 호출하고 브라우저에 관계없이 올바른 URL로 이동하는지 확인하려면 어떻게해야합니까?
CSS

71

TypeScript 사용자 :

OP가 자바 스크립트에 대해 묻는 것을 알고 있지만 가져온 기능을 염탐하려는이 유형의 사용자를 위해 여기에 할 수있는 작업이 있습니다.

테스트 파일에서 함수 가져 오기를 다음에서 변환하십시오.

import {foo} from '../foo_functions';

x = foo(y);

이에:

import * as FooFunctions from '../foo_functions';

x = FooFunctions.foo(y);

그런 다음에 감시 할 수 있습니다 FooFunctions.foo:)

spyOn(FooFunctions, 'foo').and.callFake(...);
// ...
expect(FooFunctions.foo).toHaveBeenCalled();

3
TypeScript 힌트를 주셔서 감사합니다. ES6 / Babel과 동일해야하지만 시도하지는 않았습니다.
hgoebl

1
별명 FooFunctions로 명시 적으로 함수를 호출하는 경우에만 작동하는 것 같습니다 . baz ()를 반환하는 팩토리 인 함수 bar ()가 있고 baz ()가 foo ()를 호출하는지 테스트하고 싶습니다. 이 방법은 해당 시나리오에서 작동하지 않는 것 같습니다.
Richard Matsen

4
별칭이 foo_functions 내 export const FooFunctions = { bar, foo }; 에서 가져오고 테스트에서 가져 오기 가 수행되는 경우 작동합니다. import { FooFunctions } from '../foo_functions'. 그러나 스파이가 작동하려면 별칭이 foo_functions 개인 구현 내에서 명시 적으로 사용되어야합니다. const result = FooFunctions.foo(params)// 스파이 보고서 전화 const result = foo(params)// 스파이 보고서 전화
Richard Matsen

2
매력처럼 일했다! 고마워요, 시간을 많이 절약했습니다!
SrAxi

1
이것은 더 이상 작동하지 않습니다Error: <spyOn> : parseCookie is not declared writable or has no setter
Ling Vu

42

내가 사용하는 2 가지 대안이 있습니다 (Jasmine 2 용)

이것은 함수가 실제로 가짜 인 것처럼 보이기 때문에 명확하지 않습니다.

test = createSpy().and.callFake(test); 

두 번째로 더 자세하고 명확하며 "더 깨끗합니다":

test = createSpy('testSpy', test).and.callThrough();

-> 재스민 소스 코드 는 두 번째 인수를 볼 수


이것은 조금 더 의미가 있고 성공으로 복제하기에 충분합니다. 나에게서 +1 감사합니다, C§
CSS

9

매우 간단한 방법 :

import * as myFunctionContainer from 'whatever-lib';

const fooSpy = spyOn(myFunctionContainer, 'myFunc');

1
import * as saveAsFunctions from 'file-saver';
..........
....... 
let saveAs;
            beforeEach(() => {
                saveAs = jasmine.createSpy('saveAs');
            })
            it('should generate the excel on sample request details page', () => {
                spyOn(saveAsFunctions, 'saveAs').and.callFake(saveAs);
                expect(saveAsFunctions.saveAs).toHaveBeenCalled();
            })

이것은 나를 위해 일했습니다.


4
답변에 설명을 추가하십시오. 코드 자체는 무슨 일이 일어나고 있는지 이해할 수없는 경우 질문하는 사람에게 도움이되지 않습니다.
chevybow

0

내 대답은 가져온 모듈에 단일 (기본 내보내기) 기능이 있다는 점에서 @FlavorScape와 약간 다릅니다.

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.