Typescript Jest测试似乎接收到了过时/不正确的源数据。

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

Typescript Jest Tests seem to be receiving outdated/incorrect source data

问题

我不确定为什么 Jest 返回的函数返回值与脚本接收的测试数据之间存在差异。

当我运行这个测试:

test('inCheck pawn-wrong-direction-black', () => {
  const fen = '6/7/8/9/10/k4K5/10/9/8/7/6 w - 0 1'
  const chess = new HexChess(fen)
  chess.put('g5', { color: WHITE, type: PAWN })
  expect(chess.inCheck()).toEqual(false)
})

测试失败,因为 chess.inCheck() 的返回值为 true。

当我运行一个包含以下内容的 ts-node 脚本:

const fen = '6/7/8/9/10/k4K5/10/9/8/7/6 w - 0 1'
const chess = new HexChess(fen)
chess.put('g5', { color: WHITE, type: PAWN })
console.log(chess.inCheck())

打印输出为 false。

两个文件的导入部分是相同的,所以我不明白为什么会有不同的结果。当调试测试时,似乎调试器也看到 false,除非调试器断点在实际测试声明内部。

还有一点值得注意的是,测试有时会从失败变为成功,这让我感到困惑,因为我不确定是什么在改变。还应该注意,HexChess 类不依赖于任何随机/第三方数据,所有函数应该是一对一的。

我尝试过使用 npm run test 和 Jest VSCode 扩展。

jest.config.js

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

package.json

"scripts": {
    "test": "jest",

我对 Jest 和 TypeScript 都相对较新,如果我遗漏了任何重要信息,请原谅。

英文:

I am unsure why there is a discrepency between the recieved function returns by Jest and test data that a script is recieving.

When I run this test:

test('inCheck pawn-wrong-direction-black', () => {
  const fen = '6/7/8/9/10/k4K5/10/9/8/7/6 w - 0 1'
  const chess = new HexChess(fen)
  chess.put('g5', { color: WHITE, type: PAWN })
  expect(chess.inCheck()).toEqual(false)
})

The test fails as the return value of chess.inCheck() is true.

When I run a ts-node script containing:

const fen = '6/7/8/9/10/k4K5/10/9/8/7/6 w - 0 1'
const chess = new HexChess(fen)
chess.put('g5', { color: WHITE, type: PAWN })
console.log(chess.inCheck())

The printed output is false.

The imports on both files are the same, so I do not see how there could be a difference of result. When debugging the test, it seems that the debugger also sees false unless the debugger breakpoint is within the actual test declaration.

It also seems like a test will occasionally change its status from failed to sucess, which confuses me as I am not sure what is changing. It should also be noted that the HexChess class does not depend on any random/third party data and all functions should be 1-1.

I have tried both npm run test and the Jest VSCode extension.

jest.config.js

/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

package.json

"scripts": {
    "test": "jest",

I am fairly new to both Jest and Typescript, so apologies if I am missing any important information.

答案1

得分: 2

在你的 HexClass 中,你从某个文件中导入方法并将它们分配为类的字段变量。这些方法接着使用 this,但是这个 this 实际上是指向函数而不是类。

这些个别的方法现在有了它们自己的作用域,但也会在你在其他地方导入这些文件作为节点模块时共享这个作用域,因为节点模块在某种程度上类似于单例(严格来说并不是,但在这里可以这样理解)。

你需要在类中定义这些方法,而不是在模块的字段变量中初始化它们。这样它们将引用类的作用域,而不会破坏类的封装性。

如果你真的想分开它们,只需这样做:

example.js

const example = (args // 从类中传入作用域) => ... body

export default example

import example from './methods/example';

class YourClass {

   example() {
      example(this.stuff) // 传入相关作用域
   }
}

此外,你正在将字段变量设置为在类作用域之外初始化的常量,例如将 _board 设置为 EMPTY_BOARD,可能是基于这些常量将被复制的假设。然而,实际发生的是所有类实例都将引用并修改相同的 "常量" EMPTY_BOARD。这意味着每个类实例都没有封装性,它们之间存在互相影响。

这里有一个示例演示了这个问题,以及一个示例展示了如何通过确保每次初始化一个新对象来修复它。

英文:

In your HexClass you are importing methods from some file and assigning them as field vars to the class. Those methods go on to use this, but that this is actually referencing the function and not the class.

The individual methods now have their own scope, but also that scope will be shared every time you import those files elsewhere as node modules act a little bit like singletons (actually, not strictly speaking, but it works to make sense of this here).

You need to define the methods in the class and not initialise them in field vars from modules. That way they will reference the class scope, and not break class encapsulation.

If you really want to split it up then just do:

example.js

const example = (args // pass in scope from class) => ... body

export default example

Class

import example from './methods/example'

class YourClass {

   example() {
      example(this.stuff) // pass in relevant scope
   }
}

In addition, you are setting field vars to constants initialised outside the class scope like _board to EMPTY_BOARD, probably on the assumption those constants will be copied. However, what actually happens is that all class instances will be referencing and mutating the same EMPTY_BOARD "constant". That means each class instance is not encapsulated and there is bleed between them.

Here is a playground that demonstrates this issue and a playground that shows how it can be fixed by ensuring a new object is initialised each time.

huangapple
  • 本文由 发表于 2023年7月28日 03:29:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76782857.html
匿名

发表评论

匿名网友

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

确定