Home > Software engineering >  MobX makeObservable does not work with Jest
MobX makeObservable does not work with Jest

Time:11-25

I am trying to test my stores with Jest and when I use makeObservable, I get the following error:

[MobX] Cannot apply 'observable' to '[email protected]': Field not found.

      23 |
      24 |   constructor() {
    > 25 |     makeObservable(this, {
         |                   ^
      26 |       todos: observable,
      27 |       filter: observable
      28 |     })

      at die (node_modules/mobx/src/errors.ts:84:15)
      at ObservableObjectAdministration.make_ (node_modules/mobx/src/types/observableobject.ts:250:17)
      at forEach (node_modules/mobx/src/api/makeObservable.ts:37:49)
          at Array.forEach (<anonymous>)
      at makeObservable (node_modules/mobx/src/api/makeObservable.ts:37:30)
      at new TodoStore (src/typings/models/ToDoStore.ts:25:19)
      at tests/looseReplaceNodes.test.ts:76:17
      at step (tests/looseReplaceNodes.test.ts:33:23)
      at Object.next (tests/looseReplaceNodes.test.ts:14:53)
      at tests/looseReplaceNodes.test.ts:8:71

Class in question:

export class TodoStore {
  todos: Todo[]
  filter: string

  constructor() {
    makeObservable(this, {
      todos: observable,
      filter: observable
    })
    this.todos = []
    this.filter = ""
  }
  createTodo(value: any) {
    this.todos.push(new Todo(value))
  }
}

This goes away when I use makeAutoObservable instead but that doesn't work for my use-case (this is a toy example). I don't want to use decorators as MobX seems to be moving away from this.

Any ideas?

CodePudding user response:

The easiest way is to rewrite it like that:

export class TodoStore {
  todos: Todo[] = []
  filter: string = ""

  constructor() {
    makeObservable(this, {
      todos: observable,
      filter: observable
    })
  }
  createTodo(value: any) {
    this.todos.push(new Todo(value))
  }
}

Or check configuration that you need to apply:

TypeScript: Set the compiler option "useDefineForClassFields": true.

Babel: Make sure to use at least version 7.12, with the following configuration:

{
    "plugins": [["@babel/plugin-proposal-class-properties", { "loose": false }]],
    // Babel >= 7.13.0 (https://babeljs.io/docs/en/assumptions)
    "assumptions": {
        "setPublicClassFields": false
    }
}

Usually it is better to call make(Auto)Observable as the last thing in constructor, or define properties right away.

  • Related