间谍模块和模拟模块功能

Nin*_*ita 5 testing mocking reactjs jestjs enzyme

我正在为我的组件编写一些测试,但我在这里遇到了一些麻烦......

这是我的游戏组件:

import React from 'react';
import User from './User';
import Board from './Board';
import Deck from './Deck';

class Game extends React.Component {
  constructor(props) {
    super(props);
    this.board = new Board();
    this.deck = new Deck();

    //some more code
  }

  componentDidMount() {
    this.initializeUser("xpto");
    //some more code
  }

  //some more code

  initializeUser(name) {
    const user = new User(name, this.deck);
    //some more code

    user.pickCards();
    //some more code
  }

  //some more code

  render() {
    return (
      <div className="game-container">
          something to show
          <div id="deck"></div>
      </div>
    );
  }
}


Game.propTypes = {
};

Game.defaultProps = {
};

export default Game;
Run Code Online (Sandbox Code Playgroud)

我的董事会类:

export default class Board {
  //some code
}
Run Code Online (Sandbox Code Playgroud)

我的甲板类:

export default class Deck {
  constructor(props) {
    //some more code

    this.cardsLeft = 52;
    this.lastPick = 0;

    //some more code
  }

  pickCards() {
    this.lastPick = 4;
    this.cardsLeft -= this.lastPick;
    const deckElem = document.getElementById("deck");
    deckElem.innerHTML = this.cardsLeft;
    return this.lastPick;
  }

  //some more code
}
Run Code Online (Sandbox Code Playgroud)

我的用户类:

class User {
  constructor(name, deck) {
    this.name = name;
    this.tableDeck = deck;
    this.cards = 0;
    //some more code
  }

  //some more code

  pickCards() {
    const newCards = this.tableDeck.pickCards();
    this.cards += newCards;
    //some code
  }

  //some more code
}

export default User;
Run Code Online (Sandbox Code Playgroud)

现在,在我的测试中,我试图测试BoardUser是否被调用以及是否pickCards()也被调用。

这是我的测试:

import React from 'react';
import { mount } from 'enzyme';
import Game from './Game';
import User from './User';
import Board from './Board';

describe('Game start', () => {
  let container;

  beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
  });

  afterEach(() => {
    document.body.removeChild(container);
    container = null;
  });

  it("test where I'm having problems", () => {
    const boardSpy = jest.spyOn(Board, 'constructor'),
      userSpy = jest.spyOn(User, 'constructor'),
      pickCardMock = jest.fn();

    User.pickCard = pickCardMock;

    const wrapper = mount(<Game />, { attachTo: container });

    expect(boardSpy).toHaveBeenCalledTimes(1);
    expect(userSpy).toHaveBeenCalledTimes(1);
    expect(pickCardMock).toHaveBeenCalledTimes(1);

    //some more code
  });

  it("example test where I need to test everything without mocks", () => {
    const wrapper = mount(<Game />, { attachTo: container });

    expect(wrapper.find("#deck").text()).toEqual('48');

    //some code
  });

  //some more tests
});
Run Code Online (Sandbox Code Playgroud)

我不想嘲笑BoardUser因为我需要一切正常。但我想监视他们以检查他们是否真的被召唤。我想pickCard()User.

我已经尝试在我的测试中使用jest.mock('./board');require('board')(例如)it()但它没有用。现在我试图监视组件构造函数。

但是expect(boardSpy).toHaveBeenCalledTimes(1)失败的说法是被调用了 0 次而不是 1 次。

并且pickCardMock似乎没有链接到User模块,因为当调试pickCard是正常功能而不是模拟功能时,也expect(pickCardMock).toHaveBeenCalledTimes(1)接收 0 而不是 1。

任何人都知道如何解决这两个问题(监视一个模块并模拟另一个模块中的函数)?

再次:

我不想模拟整个测试套件的东西,我只想 模拟单个测试(并且我希望能够监视模块调用)。

您可以在此处找到所有这些代码。

hel*_*joe 0

如果您还没有尝试过:

您可以User.pickCard使用进行监视jest.spyOn(User.prototype, 'pickCard')

监视BoardUser保持原始实现的另一种选择是jest.requireActual

import Board from './Board';

jest.mock('./Board', () => {
  const BoardSpy = jest.requireActual('./Board').default;
  return {
    default: jest.fn((...args) => new BoardSpy(...args)),
    __esModule: true,
  };
});

it('instantiates a Board', () => {
  const board = new Board();
  expect(Board).toBeCalled();
});
Run Code Online (Sandbox Code Playgroud)