簡體   English   中英

如何使用Jasmine和TypeScript監視構造函數

[英]How to spy on constructor using Jasmine and TypeScript

有沒有辦法使用Jasmine和Typescript監視構造函數?

有爭議的建議解決方案使用Jasmine監視構造函數無效,因為TypeScript不會在window上公開全局聲明

這是我的用例:

// higher-order function returns validation function with max length
const maxLengthValidator = maxLength => value => value.length > maxLength;

class Book {
  // will be a different function instance each time the Book object is
  // created causing the following test to fail
  nameValidator = maxLengthValidator(42);
  name = null;
  constructor (name) { this.name = name; }
}

class Library {
  persons = [];
  storeBook (book) { this.persons.push(book); }
  createBook (name) { this.storeBook(new Book(name)); }
}

測試失敗:

it('createBook passes new book with provided name to storeBook', () => {
  const lib = new Library();
  spyOn(lib, 'storeBook');
  lib.createBook('Start with Why');
  expect(lib.storeBook).toHaveBeenCalledWith(new Book('Start with Why'));
  // Result: Expected spy storeBook to have been called with
  // [ Book({ name: 'Start with Why', nameValidator: Function }) ]
  // but actual calls were
  // [ Book({ name: 'Start with Why', nameValidator: Function }) ]
});

在測試中,我不太在意構造函數的作用。 我只需要驗證是否已使用正確的參數調用了它。 這甚至聽起來像是模擬的正確用例。

可以使用它們的toString值比較兩個函數。 您可以添加自定義相等性測試器或添加新的匹配器。

添加自定義相等測試器

function replacer(k, v) {
    if (typeof v === 'function') {
        v = v.toString();
    }
    return v;
}

function stringifyEquality(a, b) {
    try {
        return JSON.stringify(a, replacer) === JSON.stringify(b, replacer) ? true : undefined;
    } catch (e) {
        return undefined
    }
}

beforeAll(() => {
    jasmine.addCustomEqualityTester(stringifyEquality);
});

it('createBook passes new book with provided name to storeBook', () => {
    const lib = new Library();
    spyOn(lib, 'storeBook');
    lib.createBook('Start with Why');
    expect(lib.storeBook.calls.mostRecent().args).toEqual([new Book('Start with Why')]);
});

添加自定義匹配器

function replacer(k, v) {
    if (typeof v === 'function') {
        v = v.toString();
    }
    return v;
}

beforeEach(() => {
    jasmine.addMatchers({
        toBeJsonEqual: function(expected){
            var one = JSON.stringify(this.actual, replacer).replace(/(\\t|\\n)/g,''),
                two = JSON.stringify(expected, replacer).replace(/(\\t|\\n)/g,'');

                return one === two;
            }
    });
});

expect(obj).toBeJsonEqual(obj2);

鏈接: 問題14541287(警察的回答)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM