Reactjs 客户端单元测试Meteor/React w/酶
因此,在Meteor/React技术堆栈中构建的大型生产应用程序中实施单元测试和集成测试时,我被一个问题困扰了好几天。我正在使用meteortesting:mocha软件包,这是meteor文档和Ezyme推荐的 我遇到的问题是,我没有真正理解如何模拟withTracker功能。我试图使用我们的dev数据库作为测试用户和模拟数据的源。所有道具都在跟踪器中生成,然后发送到它包装的组件。(下面的代码示例)。我遇到的另一个问题是,我们正在使用meteor:universe进行i18n国际化。安装组件时,它会显示纯文本,而不是翻译的内容。想知道附近是否有工作。提前谢谢 我正在测试的组件: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国际化。安装组件时
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的翻译文本
- 从数据库中提取模拟数据,而不是手动创建它