用酶测试连接的组件

时间:2019-04-08 18:02:42

标签: reactjs redux react-redux enzyme

我正在学习通过store factory来建立一个{jotto: 'foo'}测试助手来测试连接的组件,该助手“创建了一个与我们的商店配置相匹配的测试商店”。在下面,您可以看到我连接的样品组件以及用于设置测试的代码,在这些代码中,我为样品组件创建了一个连接的浅酶包装纸。但是,似乎我正在传递给样本组件的初始状态,在这种情况下,import React from 'react'; import {connect} from 'react-redux'; const SampleComponent = (props) => { console.log(props); return ( <div>This is a sample component!</div> ); }; const mapStateToProps = (state) => ({ jotto: state.jotto, }); export default connect(mapStateToProps)(SampleComponent); 在创建此浅层包装时没有传递给样本组件。我做错了什么,在运行酶测试时如何正确地重新创建必要的存储配置?谢谢!

示例组件:

import * as jottoActionTypes from 'actionTypes/jottoActionTypes';

export const initialState = {
  isSuccess: false,
};

const jotto = (state = initialState, action) => {
  switch (action.type) {
    case jottoActionTypes.CORRECT_GUESS:
      return {
        ...state,
        isSuccess: true,
      };
    default:
      return state;
  }
};

export default jotto;

减速器

import {combineReducers} from 'redux';
import {connectRouter} from 'connected-react-router';
import jotto from 'reducers/jottoReducer';

export default (historyObject) => combineReducers({
  jotto,
  router: connectRouter(historyObject),
});

根部减速器:

import React from 'react';
import {shallow} from 'enzyme';
import {createStore} from 'redux';
import rootReducer from 'reducers/rootReducer';
import SampleComponent from './sampleComponent';

export const storeFactory = (initialState) => createStore(rootReducer, initialState);

const store = storeFactory({jotto: 'foo'});
const wrapper = shallow(<SampleComponent store={store} />).dive();
console.log(wrapper.debug());

// Result:
      { store:
         { dispatch: [Function: dispatch],
           subscribe: [Function: subscribe],
           getState: [Function: getState],
           replaceReducer: [Function: replaceReducer],
           [Symbol(observable)]: [Function: observable] },
        jotto: undefined,
        dispatch: [Function: dispatch],
        storeSubscription:
         Subscription {
           store:
            { dispatch: [Function: dispatch],
              subscribe: [Function: subscribe],
              getState: [Function: getState],
              replaceReducer: [Function: replaceReducer],
              [Symbol(observable)]: [Function: observable] },
           parentSub: undefined,
           onStateChange: [Function: bound onStateChange],
           unsubscribe: [Function: unsubscribe],
           listeners:
            { clear: [Function: clear],
              notify: [Function: notify],
              get: [Function: get],
              subscribe: [Function: subscribe] } } }

设置测试:

SELECT [PROP],M1,M2,M3 
FROM (SELECT Prop,
            Entry,  
            CAST( MX AS varchar(max)) AS MX 
    FROM GA_Financial.dbo.tblSAP AS S
    LEFT JOIN tblMX AS M on S.MDY = M.Datefield) as Tab1
PIVOT(
    SUM(entry) FOR MX  IN (M1,M2,M3)) as TAb2;

2 个答案:

答案 0 :(得分:1)

仅需了解有关Udemy课程的知识,这不是最好的学习工具。讲师使用data attributes进行测试,这对于jestenzyme测试来说是不必要的(他们还会使DOM充满未使用的属性)。

此外,她的代码经验大约是初学者,她犯了很多错误和奇怪的代码选择。就是说,从中学到什么,然后开始研究那些维护流行的npm软件包的人所进行的测试(记录最齐全和最受欢迎的软件包将包含测试,它们将教给您unit和{ {1}}测试)。

无论如何,我离题了,您有两种选择来测试integration

  1. container export / classpure functionshallow包裹起来,并用假道具进行更新(非常容易,头痛程度减轻,并且更常见)
  2. 将组件包装在redux mount中,然后将React-router-dom的<Provider>包装起来,然后<MemoryRouter>(可能会变得非常复杂,因为它需要对酶有半深的了解以及安装组件时它如何解释DOM,redux的动作/缩减器流程,如何创建模拟实现和/或模拟文件,以及如何正确处理基于mount的动作)。

有效示例(单击promise标签以运行测试;在下面提到的目录中找到Tests

Edit Testing Redux Component


注意:Codesandbox当前具有一些测试限制,如下所述,因此请针对您的本地项目进行调整。

containers / Dashboard / __ tests __ / UnconnectedDashboard.test.js (您可以.tests.js轻松包装此未连接的组件以对其深层嵌套的子节点进行断言)

mount

容器/仪表板/ __ tests __ / ConnectedDashboard.test.js

import { Dashboard } from "../index.js";

/* 
   codesandbox doesn't currently support mocking, so it's making real
   calls to the API; as a result, the lifecycle methods have been
   disabled to prevent this, and that's why I'm manually calling
   componentDidMount.
*/

const getCurrentProfile = jest.fn();

const fakeUser = {
  id: 1,
  name: "Leanne Graham",
  username: "Bret",
  email: "Sincere@april.biz",
  address: {
    street: "Kulas Light",
    suite: "Apt. 556",
    city: "Gwenborough",
    zipcode: "92998-3874",
    geo: {
      lat: "-37.3159",
      lng: "81.1496"
    }
  },
  phone: "1-770-736-8031 x56442",
  website: "hildegard.org",
  company: {
    name: "Romaguera-Crona",
    catchPhrase: "Multi-layered client-server neural-net",
    bs: "harness real-time e-markets"
  }
};

const initialProps = {
  getCurrentProfile,
  currentUser: {},
  isLoading: true
};

describe("Unconnected Dashboard Component", () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<Dashboard {...initialProps} />);
    wrapper.instance().componentDidMount();
  });

  afterEach(() => wrapper.unmount());

  it("initially renders a spinnner", () => {
    expect(getCurrentProfile).toHaveBeenCalled();
    expect(wrapper.find("Spinner")).toHaveLength(1);
  });

  it("displays the current user", () => {
    wrapper.setProps({ currentUser: fakeUser, isLoading: false });
    expect(getCurrentProfile).toHaveBeenCalled();
    expect(wrapper.find("DisplayUser")).toHaveLength(1);
  });

  it("displays a signup message if no users exist", () => {
    wrapper.setProps({ isLoading: false });
    expect(getCurrentProfile).toHaveBeenCalled();
    expect(wrapper.find("DisplaySignUp")).toHaveLength(1);
  });
});

答案 1 :(得分:0)

解决方案:考虑到我正在使用connected-react-router,我忘记了root减速器的浏览器参数。

import rootReducer from 'reducers/rootReducer';
import {createBrowserHistory} from 'history';


export const storeFactory = (initialState) => createStore(rootReducer(createBrowserHistory()), initialState);