在使用Jest进行测试时,类的行为出现了意外情况。

huangapple go评论76阅读模式
英文:

unexpected behaviors on classes when testing with jest

问题

我在我的项目上进行一些测试,遇到了一些奇怪的行为。

我的代码看起来像这样:

export class Variable {
  b;

  constructor() {
    this.b = 'B';
  }

  changeValue = () => {
    this.b = 'changed B';
  };
}

export class DerivedVariable {
  v;

  constructor(v: Variable[]) {
    this.v = v;
  }
}

export class Store {
  a;

  v;

  initialize = () => {
    this.a = new Variable();
  };

  get computedValue() {
    return [this.a];
  }

  get computedInstances() {
    return new DerivedVariable(this.computedValue);
  }
}

我的测试代码:

test('test', () => {
    const { a, computedValue, computedInstances, initialize } = new Store();

    initialize();

    expect(computedValue[0].b).toBe('B');

    computedValue[0].changeValue();

    expect(a.b).toBe('changed B');

    expect(computedInstances.v[0].b).toBe('changed B');
});

我想运行initialize函数会填充类变量,从而使测试通过。

然而,测试的结果却返回了类似于:

TypeError: Cannot read properties of undefined (reading 'b')

      24 |     initialize();
      25 |
    > 26 |     expect(computedValue[0].b).toBe('B');

Jest在创建类实例时是否具有异步行为呢?

提前感谢。

  • 顺便说一下,当调用一个会改变类变量的函数后,我遇到了类似的问题,我认为这两个问题可能有关。
英文:

I'm working on some tests on my project, and have run in to some weird behaviors.

My code looks something like this:

export class Variable {
  b;

  constructor() {
    this.b = 'B';
  }

  changeValue = () => {
    this.b = 'changed B';
  };
}

export class DerivedVariable {
  v;

  constructor(v: Variable[]) {
    this.v = v;
  }
}

export class Store {
  a;

  v;

  initialize = () => {
    this.a = new Variable();
  };

  get computedValue() {
    return [this.a];
  }

  get computedInstances() {
    return new DerivedVariable(this.computedValue);
  }
}

and my test code:

test('test', () => {
    const { a, computedValue, computedInstances, initialize } = new Store();

    initialize();

    expect(computedValue[0].b).toBe('B');

    computedValue[0].changeValue();

    expect(a.b).toBe('changed B');

    expect(computedInstances.v[0].b).toBe('changed B');
  });

I figured running the initialize function would populate the class variable, which would allow the test to pass.

However, the results of the test returns something like:

 TypeError: Cannot read properties of undefined (reading 'b')

      24 |     initialize();
      25 |
    > 26 |     expect(computedValue[0].b).toBe('B');

Does jest have an asynchronous behavior when it comes to creating class instances?

Thanks in advance.

  • On a side note, I've run into a similar issue when testing with class variables after calling a function that mutates it, I assume the two issues are related.

答案1

得分: 0

我很难相信我错过了如此明显的东西,

但我通过一些排除法和研究找出了问题所在。

我遇到了一个stackoverflow问题,它引导我朝着正确的方向前进。

显然,关于箭头函数、词法作用域等方面都没有问题,

我只是忘记了JavaScript中对象赋值的工作原理。

重新分配变量a将填充变量的内存地址到另一个值,

而测试代码中的解构a将指向“旧”的对象。

在代码中:

test('test', () => {
    const { a, computedValue, computedInstances, initialize } = new Store();
    // 变量a指向初始值,这将是undefined

    initialize(); 
    // 此时,a被分配了一个新创建的变量,这将使解构的"a"在这一点上过时
  });
英文:

wow, I can't believe I missed something so obvious,

but I was able to figure out what was wrong with some process of elimination and research.

I ran into a stackoverflow question which led me to the right direction.

Apparently there were no problems at all regarding arrow functions, lexical scopes and whatnot,

I had just forgotten about how object assignment in javascript works.

Reassigning the variable a would populate the variable with a memory address to another value,

and the destructured a in the test code would point to the "old" object

In code:

test('test', () => {
    const { a, computedValue, computedInstances, initialize } = new Store();
    // the variable a points to the initial value, which would be undefined

    initialize(); 
    // at this point, a is assigned a newly created Variable, which would make the destructured "a" obsolete at this point
  });

huangapple
  • 本文由 发表于 2023年2月24日 11:00:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75552254.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定