首页 > 解决方案 > 单元测试时修改 UI

问题描述

只是好奇在这种情况下最佳策略是什么:

  1. 测试注销功能(带有注销按钮的标题)
  2. 单击该按钮时, Idispatch(Logout)会更改我的 redux reducer 的状态:

    #action-creator.js

    return { type: LOGOUT };

    #reducers.js

    case LOGOUT: return { ...state, loggedin: false }

在我的Header我基本上有以下几点:

const user_state = useSelector(state => state.user)
...
{ user_state.loggedin ? <button>Logout</button> : <button>Login</button> }

因此,在我的测试中,除其他外,我想测试单击 Logout 按钮时 UI 是否发生变化:

test('Can logout', () => {

let store = mockStore({
    user: {
        loggedin: true // simulate logged in state to display "Logout"
    }
});

const { getByText } = render(<Provider store={store}><Header/>. 
</Provider>);

fireEvent.click(getByText('Logout'))

// ????

});

理想情况下,我想测试expect(getByText("Login")).toBeTruthy();,但显然,我的模拟状态不会改变......我是否应该使用真实商店初始化测试,然后以某种方式更新它,以便在fireEvent触发时,状态实际更新并呈现登录按钮.

标签: reactjsreact-reduxjestjsreact-testing-library

解决方案


你可以有这种方法:

登录组件单元测试

测试单击按钮时登录 redux 操作是否正确调度(正确的操作类型,正确的参数),测试视觉元素是否正确(例如加载微调器)。如果这是一个异步操作,请使用Jest 实用程序监视操作功能:

const loginFunctionSpy = jest.spyOn(Module, 'loginAction');

所以这里没有测试成功登录的 UI 后果,因为您的商店确实被模拟了(并且 UI 依赖于商店状态)。但这在我看来很好,因为您还测试了 Redux 设置,以及在用户登录时负责 UI 的其他组件。

还原

负责登录动作的单元测试reducer:成功登录后正确更新存储(设置了存储中的用户),测试同步和异步动作。Reducer 在设计上易于测试(因为它或多或少是一个状态机)。

主页组件(登录成功后显示)

测试如果 store 包含登录的用户,一切都正确显示。测试如果用户不在商店,用户被重定向到其他路线(比如/登录)。

除此之外,您可以使用Cypress进行适当的 E2E 测试,例如在没有任何模拟的情况下测试整个工作流程。

主要思想是

  • 独立测试零件(组件,减速器),
  • 测试“管道”(redux 由组件正确调度,组件在每个商店配置中的行为正确)
  • 主要用例的 E2E 测试以涵盖所有部分的集成。

在我看来,这将是一个可接受的策略(实际上是我用于测试的策略),但这种方法可能有更好的选择或“测试漏洞”。我很乐意就此进行辩论并实际上对其进行改进:)​​。


推荐阅读