這是本文件的舊版!
React - How to test component with static method?
Problem
在撰寫程式時,我會習慣將同性質的utility method放在同一個class中。以實作Login、Logout的功能來說,我就會建立一個class叫Auth,會包含以下methods:
import React, { Component } from 'react'; const session_token_key = 'session_token'; export default class Auth extends Component { static signIn(username, password){ // check credential sessionStorage.setItem(session_token_key, 'session_info'); } static signOut(){ sessionStorage.clear(); } static checkLogin(){ if( !sessionStorage.getItem(session_token_key) ) { throw new Error("no session info"); } } };而Logout的元件中,則會透過Auth.signOut去執行登出的動作:
import React, { useContext } from 'react'; import Auth from './Auth' import { NavItem, NavLink} from 'reactstrap'; import { AuthContext } from './AuthContext'; function Logout(){ const [ authState, setAuthState ] = useContext(AuthContext); const signOut = ()=>{ Auth.signOut(); setAuthState(false); window.location.href = '/'; }; return ( <NavItem aria-label="logout-nav-item" className="d-md-down-none" onClick={signOut}> <NavLink href="#" ><i className="icon-logout"></i></NavLink> </NavItem> ); } export default Logout;在先前針對useContext的使用文章中,參考過別人使用jest mock static的寫法如下:
const auth_do_nothing = jest.fn(); auth_do_nothing.mockImplementation(()=>{}); Auth.signOut = auth_do_nothing.bind(Auth);但這寫法存在restore的問題,會將狀態延續至下一個testcase中;因此本篇文章將分享透過Sinon去mock static method並且清除mock狀態的做法。