bestsource

재스민을 사용하여 객체가 없는 기능을 염탐하기

bestsource 2023. 10. 1. 21:06
반응형

재스민을 사용하여 객체가 없는 기능을 염탐하기

저는 Jasmine을 사용하고 있으며 어떤 개체와도 연관되지 않은 많은 기능이 있는 라이브러리 js 파일을 가지고 있습니다(즉, 글로벌입니다).이 기능들을 염탐하려면 어떻게 해야 합니까?

윈도우/문서를 객체로 사용해 보았지만, 기능이 호출되었는데도 스파이가 작동하지 않았습니다.다음과 같이 가짜로 포장해 보았습니다.

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

테스트를 해봅니다.

expect(fakeElement.fakeMethod).toHaveBeenCalled();

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

함수를 정의하는 경우:

function test() {};

그렇다면 이는 다음과 같습니다.

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

그렇게spyOn(window, 'test')효과가 있을 겁니다

그렇지 않은 경우 다음 작업도 수행할 수 있어야 합니다.

test = jasmine.createSpy();

이 중 아무 것도 작동하지 않으면 설정에 다른 문제가 발생합니다.

내 생각엔 당신의fakeElement기술은 뒤에서 일어나고 있는 것 때문에 효과가 있습니다.원래의 globalMethod는 여전히 동일한 코드를 가리킵니다.스파이가 하는 일은 그것을 대리하는 것이지만, 사물의 맥락에서만 가능합니다.만약 당신이 가짜 요소를 통해 당신의 테스트 코드를 호출할 수 있다면 그것은 효과가 있겠지만, 당신은 글로벌 fns를 포기할 수 있습니다.

스크립트 사용자 입력:

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();

제가 사용하는 대안은 2가지가 있습니다(재스민 2용).

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

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

두 번째로 더 장황하고, 더 명확하고, 더 "깨끗한":

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

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

매우 간단한 방법:

import * as myFunctionContainer from 'whatever-lib';

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

TypeScript 솔루션

바꾸기import:

import { yourGlobalFunction } from '../your-global-functions';

다음 항목 포함:

import * as Functions from '../your-global-functions';

그러면:

spyOnProperty(Functions, 'yourGlobalFunction').and.returnValue(() => 'mock return value');
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();
            })

저는 이게 통했어요.

우리가 주로 따르는 접근 방식은 다음과 같습니다.

utils.ts모든 글로벌 유틸리티에 대한 파일:

function globalUtil() {
  // some code
}

abc.component.ts:

function foo {
  // some code
  globalUtil();  // calls global function from util.ts
}

재스민 테스트를 작성하는 동안function foo (), 다음과 같이 globalUtil 기능을 스파이킹할 수 있습니다.

abc.component.spec.ts:

import * as SharedUtilities from 'util.ts';

it('foo', () =>
{
  const globalUtilSpy = jasmine.createSpy('globalUtilSpy');
  spyOnProperty(SharedUtilities, "globalUtilSpy").and.returnValue(globalUtilSpy);
  
  foo();
  expect(globalUtilSpy).toHaveBeenCalled();
});

가져온 모듈에 단일(기본 내보내기) 기능이 있다는 점에서 @FlavorScape와 답변이 약간 다르며 다음 작업을 수행했습니다.

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');

제안된 솔루션이 제게 맞지 않아 새로운 방법을 찾았습니다. :( 그래서 이렇게 하면 됩니다.

import * as FooFunctions from 'foo-functions';

spyOnProperty(FooFunctions, 'foo').and.returnValue(jasmine.createSpy());

하고싶으면callThrough:

import * as FooFunctions from 'foo-functions';

const originalFn = FooFunctions.foo;
spyOnProperty(FooFunctions, 'foo').and.returnValue(
    jasmine.createSpy().and.callFake(originalFn)
);

좀 더 편리하게 하기 위해 도우미를 만들었습니다.다음과 같이 사용할 수 있습니다.

import * as FooFunctions from 'foo-functions';

spyOnFunction(FooFunctions, 'foo'); // to call through
spyOnFunction(FooFunctions, 'foo').and.callFake(...) // to call fake
spyOnFunction(FooFunctions, 'foo').and... // to do something else

도우미 코드는 다음과 같습니다.

function spyOnFunction<T, K extends keyof T>(source: T, originalFnKey: K): jasmine.Spy {
    const originalFn: T[K] = source[originalFnKey];

    if (!isFunction(originalFn)) {
        throw new Error('[spyOnFunction] spy target must be a function');
    }

    const spy: jasmine.Spy = jasmine.createSpy().and.callFake(originalFn);

    spyOnProperty(source, originalFnKey).and.returnValue(spy);

    return spy;
}

function isFunction(item: unknown): item is (...args: unknown[]) => unknown {
    return typeof item === 'function';
}

그게 가장 쉬운 방법인 것 같습니다.

const funcSpy = spyOn(myFunc, 'call');

언급URL : https://stackoverflow.com/questions/9510148/using-jasmine-to-spy-on-a-function-without-an-object

반응형