简体   繁体   English

为 React 模块编写单元测试时如何模拟“this”?

[英]How do I mock "this" when writing a unit test for a React module?

I'm writing a React app where the App.js has a lot of logic inside it tying together the rest of the components and keeping a coherent state.我正在编写一个 React 应用程序,其中 App.js 内部有很多逻辑将其余组件联系在一起并保持一致状态。 I have moved some of the code that were originally in App.js to helpermodule.js and bind the imported functions so that they can manipulate the state of the App component.我已经将原本在 App.js 中的一些代码移到了 helpermodule.js 并绑定了导入的函数,以便它们可以操纵 App 组件的状态。

This is my setup:这是我的设置:

App.js应用程序.js

import helperFunction from './helpermodule'

class App extends Component {
  constructor(props) {
    super(props)

    this.state = { foo: 'bar' }
    this.helperFunction = helperFunction.bind(this)
  }
}

helpermodule.js辅助模块.js

function helperFunction() {
  this.setState({
    bar: 'calculated' + this.state.foo,
  })
}

export { helperFunction }

And I want to write a unit test for the function(s) inside the helpermodule.我想为 helpermodule 中的函数编写一个单元测试。 I can't find the relevant parts in the Enzyme or Jest documentation where this is covered.我在 Enzyme 或 Jest 文档中找不到相关部分。 The goal is to see what effect helperFunction has on the App state.目标是查看 helperFunction 对 App 状态有什么影响。

I have tried things like this我试过这样的事情

test('helperFunction', () => {
  let state = { foo: 'bar' }
  let setState = (obj) => { this.state = obj }

  return expect(helperFunction().bind(this))
    .toBe({
      ...newShift,
      id: 0,
    })
}

But that just returns an error;但这只会返回一个错误; TypeError: Cannot read property 'state' of undefined . TypeError: Cannot read property 'state' of undefined Perhaps my entire approach is wrong so the problem can be circumvented but I'm not sure.也许我的整个方法都是错误的,所以可以规避这个问题,但我不确定。

Don't use this.setState in an external function不要在外部函数中使用 this.setState

helpermodule.js辅助模块.js

function helperFunction(stateFoo) {
  return {bar: 'calculated' + stateFoo};
}

export { helperFunction }

Then use the result to set state in the component.然后使用结果在组件中设置状态。 Also don't setState in constructor.也不要在构造函数中设置状态。

import helperFunction from './helpermodule'

class App extends Component {
  constructor(props) {
    super(props)

    this.state = { foo: 'bar', ...helperFunction('bar') }
  }
}

This will make testing easier as well as being a better structure in general.这将使测试更容易,并且总体上是一个更好的结构。

no idea why would you follow this approach it is so weird and hard to follow and maintain but for the sake of your argument.不知道你为什么要遵循这种方法,但为了你的论点,它是如此奇怪和难以遵循和维护。 the issue is that you are passing this to the bind while this has no property of state or setState so you should pass a mocked this instead.问题是您将this传递给绑定,而this没有statesetState属性,因此您应该传递一个模拟的this

here is how it could go这是它的方式

describe('helperFunction', () => {
    function helperFunction() {
        // @ts-ignore
        this.setState({
            // @ts-ignore
            bar: 'calculated' + this.state.foo,
        })
    }

    it('updates the provided stateHolder', () => {
        const stateHolder = {
            state: { foo: 'bar' },
            // don't use arrow function otherwise it won't react the state via this
            setState(obj: any) {
                this.state = obj;
            },
        };

        const importedHelperFunction = helperFunction.bind(stateHolder);
        importedHelperFunction();

        expect(stateHolder.state.foo).toBe('calculatedbar');
    });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在对 class 方法进行单元测试时,我如何模拟它调用的 function - 在导入的模块中定义? - When unit testing a class method, how do I mock a function it calls--one defined in an imported module? 如何在AngularJS单元测试中模拟promise的结果? - How do I mock the result of a promise in an AngularJS unit test? 如何模拟“ <script>” in react jest unit test - How to mock a “<script>” in react jest unit test 在尝试模拟 localStorage 时,如何处理来自 Test in react 的 JSON.parse 错误? - How do I deal with a JSON.parse error coming from a Test in react when trying to mock localStorage? 如何在单元测试中注入第三方AngularJS模块? - How do I inject a third party AngularJS module in a unit test? 单元测试:如何在反应中模拟 document.getElementById()? - Unit Test: How to mock document.getElementById() in react? 如何在AngularJS Jasmine单元测试中模拟返回promise的服务? - How do I mock a service that returns promise in AngularJS Jasmine unit test? 如何将模拟服务注入过滤器的单元测试? - How can i inject a mock service into a unit test for a filter? Angular - 如何在单元测试中模拟外部 function? - Angular - How can I mock an external function in a unit test? 如何在 JS 单元测试中模拟静态变量? - How can I mock a static variable in JS unit test?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM