I'm writing some tests for my component but I'm facing some troubles here...
Here is my Game component:
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;
My Board class:
export default class Board {
//some code
}
My Deck class:
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
}
My User class:
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;
Now, at my tests I'm trying to test if the Board and User are called and if the pickCards() is called too.
Here are my tests:
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
});
I don't want to mock Board and User because I need everything work normally on it. But I want to spy them to check if they were really called. And I want to mock pickCard() from User.
I already tried to use jest.mock('./board'); and require('board') (for example) only inside my it() test but it didn't work. And now I'm trying to spy the components constructors.
But the expect(boardSpy).toHaveBeenCalledTimes(1) fails saying that was called 0 times and not 1 time.
And the pickCardMock seems not being linked to the User module because when debugging pickCard is a normal function and not a mock function and expect(pickCardMock).toHaveBeenCalledTimes(1) receives 0 too instead of 1.
Anyone knows how to solve these two problems (spy a module and mock a function in another module)?
Again:
I don't want to mock things for the whole test suite, I just want to mock for a single test (and I want to be able to spy a module call).
You can find all this code here.