簡體   English   中英

Mocking 向上 static 方法開玩笑

[英]Mocking up static methods in jest

我在開玩笑的 static 方法上遇到了麻煩 mocking。 想象一下你有一個 class A 和一個 static 方法:

export default class A {
  f() {
    return 'a.f()'
  }

  static staticF () {
    return 'A.staticF()'
  }
}

和一個進口A的class B

import A from './a'

export default class B {
  g() {
    const a = new A()
    return a.f()  
  }

  gCallsStaticF() {
    return A.staticF()
  }
}

現在你想模擬 A。模擬 f() 很容易:

import A from '../src/a'
import B from '../src/b'

jest.mock('../src/a', () => {
  return jest.fn().mockImplementation(() => {
    return { f: () => { return 'mockedA.f()'} }
  })
})

describe('Wallet', () => {
  it('should work', () => {
    const b = new B()
    const result = b.g()
    console.log(result) // prints 'mockedA.f()'
  })
})

但是,我找不到任何關於如何模擬 A.staticF 的文檔。 這可能嗎?

您可以將模擬分配給靜態方法

import A from '../src/a'
import B from '../src/b'

jest.mock('../src/a')

describe('Wallet', () => {
    it('should work', () => {
        const mockStaticF = jest.fn().mockReturnValue('worked')

        A.staticF = mockStaticF

        const b = new B()

        const result = b.gCallsStaticF()
        expect(result).toEqual('worked')
    })
})

希望對你有幫助

// code to mock
export class AnalyticsUtil {
    static trackEvent(name) {
        console.log(name)
    }
}

// mock
jest.mock('../src/AnalyticsUtil', () => ({
    AnalyticsUtil: {
        trackEvent: jest.fn()
    }
}))
// code to mock
export default class Manager {
    private static obj: Manager
    
    static shared() {
        if (Manager.obj == null) {
            Manager.obj = new Manager()
        }
        return Manager.obj
    }
    
    nonStaticFunc() {
    }
}

// mock
jest.mock('../src/Manager', () => ({
    shared: jest.fn().mockReturnValue({
        nonStaticFunc: jest.fn()
    })
}))
// usage in code
someFunc() {
    RNDefaultPreference.set('key', 'value')
}

// mock RNDefaultPreference
jest.mock('react-native-default-preference', () => ({
    set: jest.fn()
}))
// code to mock
export namespace NavigationActions {
    export function navigate(
      options: NavigationNavigateActionPayload
    ): NavigationNavigateAction;
}

// mock
jest.mock('react-navigation', () => ({
    NavigationActions: {
        navigate: jest.fn()
    }
}))

我設法使用原型在__mocks__文件夾中的一個單獨文件中模擬它。 所以你會這樣做:

function A() {}
A.prototype.f = function() {
    return 'a.f()';
};
A.staticF = function() {
    return 'A.staticF()';
};
export default A;

我們需要創建一個模擬並將模擬方法的可見性提供給測試套件。 以下帶有評論的完整解決方案。

let mockF; // here we make variable in the scope we have tests
jest.mock('path/to/StaticClass', () => {
  mockF = jest.fn(() => Promise.resolve()); // here we assign it
  return {staticMethodWeWantToMock: mockF}; // here we use it in our mocked class
});

// test
describe('Test description', () => {
  it('here our class will work', () => {
    ourTestedFunctionWhichUsesThisMethod();
    expect(mockF).toHaveBeenCalled(); // here we should be ok
  })
})

笑話間諜

我選擇了使用jest.spyOn的路線。

例子

encryption.ts

export class Encryption {
  static encrypt(str: string): string {
     // ...
  }

  static decrypt(str: string): string {
    // ...
  }
}

property-encryption.spec.ts

import { Encryption } from './encryption'
import { PropertyEncryption } from './property-encryption'

describe('PropertyEncryption', () => {
  beforeAll(() => {
    jest
      .spyOn(Encryption, 'encrypt')
      .mockImplementation(() => 'SECRET')
    jest
      .spyOn(Encryption, 'decrypt')
      .mockImplementation(() => 'No longer a secret')
  })

  it("encrypts object values and retains the keys", () => {
    const encrypted = PropertyEncryption.encrypt({ hello: 'world' });

    expect(encrypted).toEqual({ hello: 'SECRET' });
  });

  it("decrypts object values", () => {
    const decrypted = PropertyEncryption.decrypt({ hello: "SECRET" });

    expect(decrypted).toEqual({ hello: 'No longer a secret' });
  });
})

在模擬構造函數上使用Object.assign允許同時模擬類及其靜態方法。 這樣做可以讓您獲得與創建具有靜態成員的類時相同的結構。

    import A from '../src/a'
    import B from '../src/b'


    jest.mock('../src/a', () =>
      Object.assign(
        jest.fn(
          // constructor
          () => ({
            // mock instance here
            f: jest.fn()
          })),
        { 
         // mock static here
          staticF: jest.fn(),
        }
      )
    )

這是一個 ES6 導入的示例。

import { MyClass } from '../utils/my-class';
const myMethodSpy = jest.spyOn(MyClass, 'foo');

describe('Example', () => {
    it('should work', () => {
        MyClass.foo();
        expect(myMethodSpy).toHaveBeenCalled();
    });
 });

暫無
暫無

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

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