Reactjs 客户端单元测试Meteor/React w/酶

Reactjs 客户端单元测试Meteor/React w/酶,reactjs,meteor,jestjs,mocha.js,enzyme,Reactjs,Meteor,Jestjs,Mocha.js,Enzyme,因此,在Meteor/React技术堆栈中构建的大型生产应用程序中实施单元测试和集成测试时,我被一个问题困扰了好几天。我正在使用meteortesting:mocha软件包,这是meteor文档和Ezyme推荐的 我遇到的问题是,我没有真正理解如何模拟withTracker功能。我试图使用我们的dev数据库作为测试用户和模拟数据的源。所有道具都在跟踪器中生成,然后发送到它包装的组件。(下面的代码示例)。我遇到的另一个问题是,我们正在使用meteor:universe进行i18n国际化。安装组件时

因此,在Meteor/React技术堆栈中构建的大型生产应用程序中实施单元测试和集成测试时,我被一个问题困扰了好几天。我正在使用meteortesting:mocha软件包,这是meteor文档和Ezyme推荐的

我遇到的问题是,我没有真正理解如何模拟withTracker功能。我试图使用我们的dev数据库作为测试用户和模拟数据的源。所有道具都在跟踪器中生成,然后发送到它包装的组件。(下面的代码示例)。我遇到的另一个问题是,我们正在使用meteor:universe进行i18n国际化。安装组件时,它会显示纯文本,而不是翻译的内容。想知道附近是否有工作。提前谢谢

我正在测试的组件:

import React, { useState } from "react";
import ABCComponent from "./ABCComponent";
import XYZ from "./XYZComponent";
import * as ROUTE_CONSTANTS from "../../global/RoutesConstants";
import { withRouter } from "react-router-dom";
import { withTracker } from "meteor/react-meteor-data";
import UserAssessments from "../../collections/UserAssessments";
import moment from "moment-timezone";
import { i18n } from "meteor/universe:i18n";

const SortDashboard = (props) => {
  const [isSkillsSort, setIsSkillSort] = useState(true);

  return (
   <div>
       {/* Contains some logic to set 'isSetSkillSort' state true or false (business logic hidden for security purposes*/}
      {isSkillsSort ? (
        <ABCComponent user={props.user} skillsSorts={props.skillsSorts} employeeList={props.directReportEmp} />
      ) : (
        <XYZComponent
          user={props.user}
          importanceSorts={props.importanceSorts}
          employeeList={props.directReportEmp}
        />
      )}
    </div>
  );
};

const SortDashboardTracker = withTracker((props) => {
  if (!props.user) return {};

  const abcSubscription = Meteor.subscribe("abcSubscription");

  if (abcSubscription.ready()) {
    const rawData = UserAssessments.find(
      { "assessor._id": Meteor.user().profile._id },
      { sort: { updatedDate: -1 } }
    ).fetch();

    rawData.forEach((assessment) => {
        //Do Something (business logic hidden for security purposes)
    });
  }

  const xyzSubscription = Meteor.subscribe("xyzSubscription");

  let directReportEmp = [];

  if (xyzSubscription.ready()) {
    directReportEmp = Meteor.users.find({ "profile.managerId": Meteor.user().username }).fetch();
  }

  return { importanceSorts, skillsSorts, directReportEmp };
})(SortDashboard);

export default withRouter(SortDashboardTracker);
import React,{useState}来自“React”;
从“/ABCComponent”导入ABCComponent;
从“/XYZ组件”导入XYZ;
从“../../global/routeConstants”导入*作为路由_常量;
从“react router dom”导入{withRouter};
从“流星/反应流星数据”导入{withTracker};
从“../../collections/UserAssessments”导入用户评估;
从“时刻时区”导入时刻;
从“流星/宇宙:i18n”中导入{i18n};
const SortDashboard=(道具)=>{
const[isSkillsSort,setIsSkillSort]=useState(true);
返回(
{/*包含一些将“isSetSkillSort”状态设置为true或false的逻辑(出于安全目的隐藏业务逻辑*/}
{伊斯基尔索特(
) : (
)}
);
};
const SortDashboardTracker=withTracker((道具)=>{
if(!props.user)返回{};
常量abcSubscription=Meteor.subscription(“abcSubscription”);
if(abcSubscription.ready()){
const rawData=UserAssessments.find(
{“assessor.\u id”:Meteor.user().profile.\u id},
{sort:{updateDate:-1}}
).fetch();
rawData.forEach((评估)=>{
//执行某些操作(出于安全目的隐藏业务逻辑)
});
}
常量xyzSubscription=Meteor.subscription(“xyzSubscription”);
设directReportEmp=[];
if(xyzSubscription.ready()){
directReportEmp=Meteor.users.find({“profile.managerId”):Meteor.user().username}.fetch();
}
返回{ImportanceSports,Skillssor,directReportEmp};
})(SortDashboard);
使用路由器导出默认值(SortDashboardTracker);
我的测试:

import {Meteor} from 'meteor/meteor';
import React from 'react';
import chai from 'chai';
import sinon, { mock } from 'sinon'
import {mount, shallow, configure, render} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {mockManager,mockEmp1,mockEmp2,mockEmp3,mockUser} from '../../mockUsers'
import SortDashboard from '../../../../imports/components/cllWizard/SortDashboard';
import { withRouter, BrowserRouter as Router } from "react-router-dom";

configure({adapter: new Adapter()});
if (Meteor.isClient) {
    describe('WizardComponent', ()=> {
        //let returnedText
         //importing the mock user we created for testing purposes
         const currentUser = mockUser
         let props = {user: currentUser}
         beforeEach(() => {
 
             // now Meteor.user() will return the user we just imported
             sinon.stub(Meteor, 'user');
             Meteor.user.returns(currentUser);
 
             // needed in methods
             sinon.stub(Meteor, 'userId');
             Meteor.userId.returns(currentUser._id); 
         });
 
         //afterEach specifies that we want to restore the user after running the test
         afterEach(() => {
             Meteor.user.restore();
             Meteor.userId.restore();
         });

        it('CLIENT: should render the Sort Dashboard', () => {
            const wrapper = mount(<Router><SortDashboard.WrappedComponent {...props}/></Router>)
            console.log(wrapper.debug())
        });
    });
}
从'Meteor/Meteor'导入{Meteor};
从“React”导入React;
从‘柴’进口柴;
从“sinon”导入sinon,{mock}
从“酶”导入{mount,shallow,configure,render};
从'enzyme-Adapter-react-16'导入适配器;
从“../../mockUsers”导入{mockManager,mockEmp1,mockEmp2,mockEmp3,mockUser}
从“../../../../imports/components/cllWizard/SortDashboard”导入SortDashboard;
从“react Router dom”导入{withRouter,BrowserRouter as Router};
配置({adapter:newadapter()});
if(Meteor.isClient){
描述('WizardComponent',()=>{
//让我们返回文本
//导入我们为测试目的创建的模拟用户
const currentUser=mockUser
让props={user:currentUser}
在每个之前(()=>{
//现在Meteor.user()将返回我们刚刚导入的用户
sinon.stub(Meteor,'用户');
Meteor.user.returns(currentUser);
//方法上需要
sinon.stub(Meteor,'userId');
Meteor.userId.returns(currentUser.\u id);
});
//afterEach指定我们希望在运行测试后恢复用户
之后(()=>{
Meteor.user.restore();
Meteor.userId.restore();
});
它('客户端:应呈现排序仪表板',()=>{
const wrapper=mount()
console.log(wrapper.debug())
});
});
}
TLDR

  • 需要测试使用withTracker和withRouter的客户端组件
  • 需要能够在测试中看到流星:宇宙:i18n的翻译文本
  • 从数据库中提取模拟数据,而不是手动创建它
问题很可能是我的态度和理解不足。请在必要时纠正我。提前感谢