Statische Methoden im Scherz verspotten

Lesezeit: 4 Minuten

Benutzeravatar von Clemens
Clemens

Ich habe Probleme, eine statische Methode im Scherz zu verspotten. Stellen Sie sich vor, Sie haben eine Klasse A mit einer statischen Methode:

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

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

Und eine Klasse B, die A importiert

import A from './a'

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

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

Jetzt wollen Sie A verspotten. Es ist einfach, f() zu verspotten:

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

Ich konnte jedoch keine Dokumentation darüber finden, wie man A.staticF mockt. Ist das möglich?

Benutzeravatar von Peter Stonham
Peter Stonham

Sie können den Mock einfach der statischen Methode zuweisen

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')
    })
})

  • Und dann kann man das auch expect(mockStaticF).toBeCalled() geben Sie Behauptungen ein, obwohl die gebundene Version nicht funktioniert (z expect(A.staticF).toBeCalled() würde werfen)

    – DavidA

    2. Dezember 2019 um 11:04 Uhr

  • Gute Lösung @Peter Du hast mir 2020 wirklich den Tag gerettet. Vielen Dank.

    – Mohit

    19. Januar 2020 um 18:08 Uhr

  • Warum bind in diesem Fall verwenden? Könnte es nicht einfacher sein, einfach zuzuordnen mockStaticF zu A.staticF? z.B A.staticF = mockStaticF

    – Todd Drinkwater

    3. Februar 2020 um 7:28 Uhr

  • kann auch ‘staticF’ außerhalb von ‘describe’ verspotten, zB jest.mock('../src/a', () => { const A = jest.fn().mockImplementation(() => { f: () => { return 'mockedA.f()'} } }); A.staticF = jest.fn(); return A; })

    – Frank

    30. April 2020 um 22:08 Uhr


  • Hier gibt es zwei Probleme, die nicht berücksichtigen, wie Jest funktioniert. Verspotten Sie niemals Methoden mit Zuweisungen wie A.staticF = mockStaticF Wenn Sie dies nicht vermeiden können, verhindert dies, dass Jest Methoden wiederherstellt, wo dies erforderlich ist, und führt möglicherweise zu einer Kreuzkontamination des Tests. Dafür ist jest.spyOn gedacht. jest.mock('../src/a') macht einen Auto-Mock, es macht statische Methode bereits zu einem Stub, der dies zulässt A.staticF.mockReturnValue('worked').

    – Estus-Kolben

    8. Februar 2021 um 12:29 Uhr


Benutzeravatar von Alex Minokis
Alex Minokis

Ich hoffe, das wird Ihnen helfen

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

  • Sehr nützliche Schnipsel! Vielen Dank!

    – friederblümle

    8. Januar 2021 um 2:27 Uhr

Ich habe es geschafft, es in einer separaten Datei in der zu verspotten __mocks__ Ordner mit Prototyping. Also würdest du tun:

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

Verwenden Object.assign auf dem Mock-Konstruktor ermöglicht das gleichzeitige Mocking der Klasse und ihrer statischen Methoden. Auf diese Weise können Sie die gleiche Struktur erreichen, die Sie erhalten, wenn Sie eine Klasse mit statischen Membern erstellen.

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

Wir müssen einen Mock erstellen und der Testsuite Sichtbarkeit für die mockierte Methode geben. Unten vollständige Lösung mit Kommentaren.

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

Benutzeravatar von CTS_AE
CTS_AE

Scherz Spione

Ich ging mit dem Weg der Verwendung jest.spyOn.

Beispiel

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

Benutzeravatar von guzmanoj
Guzmanoj

Hier ist ein Beispiel mit einem ES6-Import.

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

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

1403920cookie-checkStatische Methoden im Scherz verspotten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy