Jest.js 在React Native中测试本机事件发射器和本机模块

5us2dqdw  于 2023-01-06  发布在  Jest
关注(0)|答案(3)|浏览(169)

我有一个React Native组件,它与一个自定义iOS类通信,因此我使用NativeModules en NativeEventEmitter向本机代码发送命令和从本机代码接收命令。

import {NativeModules, NativeEventEmitter} from 'react-native';

/* inside the constructor I do some setup: */
const { NetworkManager } = NativeModules;
const emitter = new NativeEventEmitter(NetworkManager);

/* here I subscribe to an event from the emitter */
public startDiscovery() {

  const deviceFoundSubscription = this._emitter.addListener(
    "DeviceDiscovered",
    (device) => this.deviceFound(device)
  );
  this.NetworkManager.startDiscovery();
}

这段代码运行得很好,但是现在我想用Jest编写一些测试,这就是我遇到的问题。我该如何继续为事件侦听器编写测试呢?我想在Jest测试中模拟DeviceDiscovered事件,然后Assert侦听器被调用。

aiqt4smr

aiqt4smr1#

为了解决我的问题,我使用一个日常的JS事件发射器来模拟RCTDeviceEventEmitter:

const EventEmitter = require('EventEmitter');
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

/**
 * Mock the NativeEventEmitter as a normal JS EventEmitter.
 */
export class NativeEventEmitter extends EventEmitter {
  constructor() {
    super(RCTDeviceEventEmitter.sharedSubscriber);
  }
}

然后在jest的setupFile中,我导入了mock来替换react-native实现。

import NativeEventEmitter from './__mocks__/nativeEventEmitter';
import { NativeModules } from 'react-native';

// Mock for my native module where I create a spy for the methods
const mockNativeModules = {
  NetworkManager: {
    startDiscovery: jest.fn(),
    stopDiscovery: jest.fn(),
    connectToHost: jest.fn(),
    sendMessage: jest.fn()
  }
};

// Mock every native module you use
Object.keys(mockNativeModules).forEach((module => {
    jest.doMock(module, () => mockNativeModules[module], { virtual:true });
}));

jest.doMock('NativeModules', () => mockNativeModules);

jest.mock('NativeEventEmitter');

最后是我的实际测试代码:

import {
  NativeModules,
  NativeEventEmitter,
} from 'react-native';

import { DiscoveryService } from '/services/discoveryService';

import { device1, device2 } from './../fixtures/devices';

const nativeEventEmitter = new NativeEventEmitter();

describe('Discovery Service', () => {

  beforeEach(() => {
    discoveryService.deviceDiscovered = jest.fn();
    discoveryService.startDiscovery();
  });

  test('Should call startDiscovery on Native Module NetworkManager', () => {

    nativeEventEmitter.emit('DeviceDiscovered', device);

    expect(NativeModules.NetworkManager.startDiscovery).toHaveBeenCalledTimes(1);
    expect(discoveryService.serverFound).toHaveBeenCalledWith(device1);
  });

  test('Should handle multiple discoveries', () => {

    nativeEventEmitter.emit('DeviceDiscovered', device1);
    expect(discoveryService.serverFound).toHaveBeenCalledWith(device1);

    nativeEventEmitter.emit('DeviceDiscovered', device2)
    expect(discoveryService.deviceFound).toHaveBeenCalledWith(device2);    
  });
});
92vpleto

92vpleto2#

在您jest/setup.js
添加你的相对路径:

jest.mock(
  '../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter',
);
but5z9lq

but5z9lq3#

jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter.js', () => {
  const { EventEmitter } = require('events');
  return EventEmitter;
});

相关问题