【发布时间】:2020-07-27 22:49:24
【问题描述】:
我正在为我的组件编写一些测试,但我在这里遇到了一些麻烦......
这是我的游戏组件:
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;
我的董事会课程:
export default class Board {
//some code
}
我的甲板课:
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
}
我的用户类:
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;
现在,在我的测试中,我正在尝试测试是否调用了 Board 和 User 以及是否也调用了 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
});
我不想模拟Board 和User,因为我需要一切正常工作。但我想监视他们以检查他们是否真的被召唤。我想从User 模拟pickCard()。
我已经尝试在我的it() 测试中使用jest.mock('./board'); 和require('board')(例如),但它不起作用。现在我正在尝试监视组件的构造函数。
但是 expect(boardSpy).toHaveBeenCalledTimes(1) 没有说被调用了 0 次而不是 1 次。
pickCardMock 似乎没有链接到User 模块,因为在调试时pickCard 是一个普通函数而不是模拟函数,expect(pickCardMock).toHaveBeenCalledTimes(1) 也收到 0 而不是 1。
有谁知道如何解决这两个问题(窥探一个模块并在另一个模块中模拟一个函数)?
再说一遍:
我不想模拟整个测试套件的东西,我只想 模拟单个测试(我希望能够监视模块调用)。
你可以找到所有这些代码here。
【问题讨论】:
-
不想模拟 Board 和 User,因为我需要一切正常工作。 - 这是集成测试,它不是独立单元测试的适当替代品. 但我想监视他们以检查他们是否真的被召唤 - 为什么?如果您的意图是保留原始实现,您只需检查 board 是 Board 的一个实例。 我已经尝试过使用 jest.mock('./board');和 require('board') - 你到底做了什么?您需要
jest.resetModules(),然后重新导入整个模块层次结构,即require依赖于Board 的组件,而不仅仅是Board。 -
@EstusFlask 我可以尝试以
instanceofBoad测试板。但是我怎样才能在包装器成为mount()之前模拟User.pickCards? -
一种简单的方法是在顶层使用
jest.mock('./user')并自动模拟这些类。可以监视构造函数而不是模拟它们,但它是不可靠的 - 构造函数本身就是一个类,而不仅仅是constructor属性,因此 spy 函数应该以一种棘手的方式从原始类继承,并且不能保证按预期工作,这违背了让它“正常工作”的目的。
标签: reactjs testing mocking jestjs enzyme