Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何测试shouldComponentUpdate方法?_Javascript_Reactjs_Testing_Enzyme_Sinon - Fatal编程技术网

Javascript 如何测试shouldComponentUpdate方法?

Javascript 如何测试shouldComponentUpdate方法?,javascript,reactjs,testing,enzyme,sinon,Javascript,Reactjs,Testing,Enzyme,Sinon,我想测试一下这个方法,shouldComponentUpdate,但是我编写的测试没有捕捉到副作用。我如何测试这个 我已经尝试了此处提出的解决方案,但其中存在一些问题,我将在代码中说明: 我尝试过使用shallow而不是mount,但当我这样做时,我的测试失败了: expect(shouldComponentUpdate).to.have.property("callCount", 1); // AssertionError: expected [Function: proxy]

我想测试一下这个方法,
shouldComponentUpdate
,但是我编写的测试没有捕捉到副作用。我如何测试这个

我已经尝试了此处提出的解决方案,但其中存在一些问题,我将在代码中说明:

我尝试过使用
shallow
而不是
mount
,但当我这样做时,我的测试失败了:

    expect(shouldComponentUpdate).to.have.property("callCount", 1);
    // AssertionError: expected [Function: proxy] to have a property 'callCount' of 1, but got 0
以下是我的组件的
shouldComponentUpdate
功能:

    shouldComponentUpdate(nextProps, nextState) {
        if (this.props.storageValue !== nextProps.storageValue) {
            localStorage.setItem(constantFile.storageKey, nextProps.storageValue);
            localStorage.setItem(constantFile.timestampKey, now());
            this.setState({
                newStorage: nextProps.storageValue
            });
            return true;
        }

        ...

        return false;
    }
这是我的测试:

    it("Test shouldComponentUpdate", () => {
        /* eslint-disable one-var */
        const wrapper = mount(
            <Provider store={store}>
                <MyComponent />
            </Provider>),
            shouldComponentUpdate = sinon.spy(CapitalHomeAccessPointContainer.prototype, "shouldComponentUpdate");
        wrapper.setProps({
            storageValue: true
        });
        expect(shouldComponentUpdate).to.have.property("callCount", 1);   
        expect(shouldComponentUpdate.returned(true)).to.be.equal(true);
  expect(localStorage.getItem(constantFile.timestampKey)).to.equal(someExpectedTimestamp);
    });
失败于

AssertionError: expected false to equal true

为什么会发生这种情况?我想
应该组件更新
应该返回
?稍后,我希望测试状态和本地存储的副作用,但我不理解这个错误。

您处理的shouldComponentUpdate生命周期是错误的。您不需要在其中设置state,而是只返回一个布尔值(true或false),让React知道何时重新呈现DOM。这允许您阻止来自外部道具的更新。例如:

shouldComponentUpdate(nextProps, nextState) {
 return this.state.newStorage !== nextState.newStorage
}
static getDerivedStateFromProps(props, state) {
  return props.storage.key !== state.storageKey 
  ? { storageKey: props.storage.key }
  : null
}
上述状态:如果当前新闻存储状态与下一个新闻存储状态不匹配,则重新呈现组件上述操作将阻止重新招标组件时的道具更改。如果更改了
存储
道具,它将不会更新此组件,因为状态未更改。您希望使用shouldComponentUpdate来防止不必要的双重重新渲染和/或防止父组件的重新渲染不必要地重新渲染子组件。在这种情况下,您不需要使用此生命周期方法

相反,您应该在渲染前使用for props更新状态,或者在渲染后使用for props更新状态

在您的情况下,因为您只想在
this.props.storageValue
发生更改时更新状态,所以您应该使用
组件diddupdate

componentDidUpdate(prevProps) {
   if (this.props.storageValue !== prevProps.storageValue) {
     localStorage.setItem(constantFile.storageKey, nextProps.storageValue);
     localStorage.setItem(constantFile.timestampKey, now());
     this.setState({ newStorage: nextProps.storageValue });
   }
}
上面检查当前道具是否与以前的道具不匹配,然后更新状态以反映更改

您将无法使用
静态getDerivedStateFromProps
,因为旧道具和新道具之间没有比较,只有与传入道具和当前状态的比较。也就是说,如果您以与存储道具直接相关的状态存储某些内容,则可以使用它。例如,如果您将道具中的密钥存储到状态中。如果道具密钥要更改,并且它与状态中的当前密钥不匹配,那么它将更新状态以反映密钥更改。在这种情况下,您将返回
对象
以更新状态,或返回
null
以不更新状态

例如:

shouldComponentUpdate(nextProps, nextState) {
 return this.state.newStorage !== nextState.newStorage
}
static getDerivedStateFromProps(props, state) {
  return props.storage.key !== state.storageKey 
  ? { storageKey: props.storage.key }
  : null
}

当涉及到测试时,您需要手动更新道具以影响状态更改。通过针对状态更改进行测试,您将间接针对
componentdiddupdate
进行测试

例如(您必须这样做,否则状态将不会更新——我还建议
导出
并导入
类,而不是使用Redux连接的组件):

从“./MyComponent.js”导入{MyComponent};
const initialProps={storageValue::};
描述(“测试组件”,()=>{
让包装纸;
在每个之前(()=>{
包装器=mount();
})
它(“当‘storageValue’道具发生更改时更新‘newStorage’状态,()=>{
setProps({storageValue:“test”});
expect(wrapper.state('NewStorage')).toEqual(…);//这应该会更新NewStorage状态
setProps({someOtherProp:“hello”)};
expect(wrapper.state('NewStorage')).toEqual(…);//这不应更新NewStorage状态
});
});

您处理的shouldComponentUpdate生命周期是错误的。您没有在其中设置状态,而是只返回一个布尔值(true或false),让React知道何时重新呈现DOM。这允许您阻止来自外部道具的更新。例如:

shouldComponentUpdate(nextProps, nextState) {
 return this.state.newStorage !== nextState.newStorage
}
static getDerivedStateFromProps(props, state) {
  return props.storage.key !== state.storageKey 
  ? { storageKey: props.storage.key }
  : null
}
上述状态:如果当前新闻存储状态与下一个新闻存储状态不匹配,则重新呈现组件。上述状态将阻止属性更改,从而无法重新呈现组件。如果更改了
存储
属性,则不会更新此组件,因为状态未更改。是否要使用shouldcomponentupdatee以防止不必要的双重重新渲染和/或防止父组件的重新渲染不必要地重新渲染子组件。在这种情况下,您不需要使用此生命周期方法

相反,您应该在渲染前使用for props更新状态,或者在渲染后使用for props更新状态

在您的情况下,因为您只想在
this.props.storageValue
发生更改时更新状态,所以您应该使用
组件diddupdate

componentDidUpdate(prevProps) {
   if (this.props.storageValue !== prevProps.storageValue) {
     localStorage.setItem(constantFile.storageKey, nextProps.storageValue);
     localStorage.setItem(constantFile.timestampKey, now());
     this.setState({ newStorage: nextProps.storageValue });
   }
}
上面检查当前道具是否与以前的道具不匹配,然后更新状态以反映更改

您将无法使用
static getDerivedStateFromProps
,因为旧的和新的道具之间没有比较,而只比较传入的道具和当前状态。也就是说,如果您以与存储道具直接相关的状态存储某个东西,则可以使用它。例如,如果您从道具和进入状态。如果道具密钥要更改并且与当前状态中的密钥不匹配,则它将更新状态以反映密钥更改。在这种情况下,您将返回
对象以更新状态,或返回
null以不更新状态

例如:

shouldComponentUpdate(nextProps, nextState) {
 return this.state.newStorage !== nextState.newStorage
}
static getDerivedStateFromProps(props, state) {
  return props.storage.key !== state.storageKey 
  ? { storageKey: props.storage.key }
  : null
}

说到测试,您需要手动更新道具以影响状态更改。通过针对状态更改进行测试,您将间接针对
componentdiddupdate
进行测试

例如(您必须这样做,否则状态将不会更新——我还建议
导出
并导入
类,而不是使用Redux连接的组件):

从“./My”导入{MyComponent}