Sử dụng Jasmine để theo dõi một chức năng mà không có đối tượng


154

Tôi mới sử dụng Jasmine và mới bắt đầu sử dụng nó. Tôi có một tệp js thư viện với rất nhiều chức năng không liên quan đến bất kỳ đối tượng nào (tức là toàn cầu). Làm thế nào để tôi đi về gián điệp các chức năng này?

Tôi đã thử sử dụng window / document làm đối tượng, nhưng điệp viên không hoạt động mặc dù chức năng được gọi. Tôi cũng đã thử bọc nó trong một đối tượng giả như sau:

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

và kiểm tra với

expect(fakeElement.fakeMethod).toHaveBeenCalled();

Điều này cũng không hoạt động vì gián điệp không hoạt động

Câu trả lời:


155

Nếu bạn đang xác định chức năng của mình:

function test() {};

Sau đó, điều này tương đương với:

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

Vì vậy spyOn(window, 'test')nên làm việc.

Nếu không, bạn cũng có thể:

test = jasmine.createSpy();

Nếu không ai trong số họ đang làm việc, một cái gì đó khác đang diễn ra với thiết lập của bạn.

Tôi không nghĩ rằng fakeElementkỹ thuật của bạn hoạt động vì những gì đang diễn ra đằng sau hậu trường. GlobalMethod ban đầu vẫn trỏ đến cùng một mã. Những gì gián điệp làm là ủy quyền nó, nhưng chỉ trong bối cảnh của một đối tượng. Nếu bạn có thể nhận được mã kiểm tra của mình để gọi thông qua fakeEuity thì nó sẽ hoạt động, nhưng sau đó bạn có thể từ bỏ fns toàn cầu.


2
Nó đã làm việc! Tôi nghĩ rằng lỗi tôi đã gây ra trước đó là tôi đã gọi spyOn bằng phương thức () thay vì phương thức. Cảm ơn!
Chetter Hummin

3
Tôi đã gặp một số vấn đề khi sử dụng spyOn (cửa sổ, 'thử nghiệm') khi sử dụng chutzpah để chạy thử nghiệm như một phần của tự động hóa do 'cửa sổ' không được chỉ định. Sử dụng jasmine.createSpy () đã khắc phục điều này.
Henners

7
jasmine.createSpy () đã làm việc hoàn hảo cho tôi. Cảm ơn!
dplass

1
sử dụng test = jasmine.createSpy();để do thám trên angularJs $anchroScrolllàm việc một cách hoàn hảo
Edgar Martinez

1
Vì một số lý do, tôi không thể làm việc theo cách nào, nhưng có thể hoàn toàn có thể là vì tôi đang cố gắng chế tạo một chức năng cửa sổ hiện có; $window.open(url, '_blank');với ý định mở một tab mới (hoặc cửa sổ tùy thuộc vào thiết lập trình duyệt). Làm thế nào tôi nên đi về việc đảm bảo rằng nó gọi chức năng này và xác minh rằng nó đang điều hướng đến đúng url bất kể trình duyệt là gì?
CSS

71

Người dùng TypeScript:

Tôi biết OP đã hỏi về javascript, nhưng đối với bất kỳ người dùng TypeScript nào gặp phải vấn đề này muốn theo dõi một chức năng đã nhập, đây là những gì bạn có thể làm.

Trong tệp thử nghiệm, chuyển đổi nhập hàm từ đây:

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

x = foo(y);

Về điều này:

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

x = FooFunctions.foo(y);

Sau đó, bạn có thể theo dõi trên FooFunctions.foo:)

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

3
Cảm ơn gợi ý TypeScript. Tương tự như nhau đối với ES6 / Babel, nhưng tôi chưa thử.
hgoebl

1
Có vẻ như nó chỉ hoạt động nếu gọi hàm một cách rõ ràng với các FooFifts bí danh . Tôi có một thanh chức năng () là một nhà máy trả về baz () và muốn kiểm tra rằng baz () gọi foo (). Phương pháp này dường như không hoạt động trong kịch bản đó.
Richard Matsen

4
Điều này sẽ hoạt động nếu bí danh được lấy bên trong foo_fifts export const FooFunctions = { bar, foo }; và việc nhập trong kiểm tra trở thành import { FooFunctions } from '../foo_functions'. Tuy nhiên, bí danh vẫn cần được sử dụng rõ ràng trong triển khai riêng tư của foo_fifts để gián điệp hoạt động. const result = FooFunctions.foo(params)// báo cáo gián điệp gọi const result = foo(params)// báo cáo gián điệp không có cuộc gọi
Richard Matsen

2
Làm việc như người ở! Cảm ơn, bạn đã tiết kiệm cho tôi rất nhiều thời gian!
SrAxi

1
Điều này không còn hoạt động nữa có mộtError: <spyOn> : parseCookie is not declared writable or has no setter
Ling Vu

42

Có 2 lựa chọn mà tôi sử dụng (cho hoa nhài 2)

Điều này không hoàn toàn rõ ràng vì có vẻ như chức năng này thực sự là giả mạo.

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

Thứ hai dài dòng hơn, rõ ràng hơn và "sạch hơn":

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

-> mã nguồn hoa nhài để xem đối số thứ hai


Điều này làm cho một chút ý nghĩa hơn và phá vỡ nó đủ xa để nhân đôi với thành công. +1 từ tôi. Cảm ơn, C §
CSS

9

Một cách rất đơn giản:

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

Điều này làm việc cho tôi.


4
Vui lòng thêm giải thích cho câu trả lời của bạn, bản thân mã không hữu ích cho người đặt câu hỏi nếu họ không thể hiểu chuyện gì đang xảy ra.
chevybow

0

Câu trả lời của tôi hơi khác với @FlavorScape ở chỗ tôi có một chức năng (xuất mặc định) trong mô-đun đã nhập, tôi đã làm như sau:

import * as functionToTest from 'whatever-lib';

const fooSpy = spyOn(functionToTest, 'default');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.