Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vitest+Typescript: TypeError: Cannot set property X of #<Y> which has only a getter #1494

Closed
6 tasks done
ffknob opened this issue Jun 15, 2022 · 7 comments
Closed
6 tasks done
Labels
good first issue Good for newcomers

Comments

@ffknob
Copy link

ffknob commented Jun 15, 2022

Describe the bug

I'm having some trouble and need some advice on creating a TS class with private/protected readonly members and have it pass my vitest tests.

asset.ts

export enum AssetType {
  STOCK,
  CRYPTO,
}

export abstract class Asset {
  protected readonly _type: AssetType;
  protected readonly _symbol: string;
  protected readonly _name: string;
  protected _amount: number;
  protected readonly _initialPrice: number;

  constructor(
    type: AssetType,
    symbol: string,
    name: string,
    amount: number,
    initialPrice: number,
  ) {
    this._type = type;
    this._symbol = symbol;
    this._name = name;
    this._amount = amount;
    this._initialPrice = initialPrice;
  }

  get type(): AssetType {
    return this._type;
  }

  get symbol(): string {
    return this._symbol;
  }

  get name(): string {
    return this._name;
  }

  get amount(): number {
    return this._amount;
  }

  set amount(amount: number) {
    this._amount = amount;
  }

  get initialPrice(): number {
    return this._initialPrice;
  }
}

stock.ts:

import { Asset, AssetType } from '@core/asset';

export class Stock extends Asset {
  constructor(
    symbol: string,
    name: string,
    amount: number,
    initialPrice: number,
  ) {
    super(AssetType.STOCK, symbol, name, amount, initialPrice);
  }
}

broker.test.ts

import { describe, it, expect, beforeAll } from 'vitest';
import { Broker } from '@core/broker';
import { Position } from '@core/position';
import { Stock } from '@core/stock';

let stock: Stock;

beforeAll(() => {
  stock = new Stock('XYZ', 'XYZ Co.', 1000, 1.0);
});

describe('addPosition', () => {
  it("should add position to the broker's positions", () => {
    const positions: Position[] = [];
    const broker: Broker = new Broker('John Smith', positions);
    const newPosition: Position = new Position(stock, 1);

    expect(broker.positions).toEqual([newPosition]);
  });
});

Result after running vitest:

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Suites 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  src/core/broker/broker.test.ts > addPosition
TypeError: Cannot set property asset of #<Position> which has only a getter
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  src/core/broker/broker.test.ts > addPosition > should add position to the broker's positions

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Error ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
TypeError: Cannot read properties of undefined (reading 'stacks')
 ❯ parseStacktrace file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-utils-timers.8a5e7cd5.js:5678:9
 ❯ printError file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:10045:18
 ❯ Vitest.printError file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:10623:12
 ❯ VerboseReporter.printTaskErrors file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:8640:22
 ❯ VerboseReporter.reportSummary file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:8591:18
 ❯ processTicksAndRejections node:internal/process/task_queues:96:5
 ❯ async VerboseReporter.onFinished file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:8486:5
 ❯ async VerboseReporter.onFinished file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:9266:5
 ❯ async Vitest.report file:/home/ffknob/Entwicklung/workspace/ffknob/x-udemy-js-unit-testing/node_modules/vitest/dist/chunk-vite-node-externalize.92c54acc.js:10574:5

So, since I'm not the one setting the property explicit with a setter, I guess that's something vitest is doing somehow...

I can manage it to work if I remove the readonly modifier and create a setter for the propertuy, but I wonder if I can pass this error without having to make changes to my code.

Any thoughts?

Thank you

Reproduction

(see example code above)

System Info

Need to install the following packages:
  envinfo
Ok to proceed? (y) 

  System:
    OS: Linux 5.17 openSUSE Tumbleweed 20220506
    CPU: (8) x64 Intel(R) Core(TM) i7-10510U CPU @ 1.80GHz
    Memory: 3.84 GB / 15.41 GB
    Container: Yes
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 16.14.0 - ~/.nvm/versions/node/v16.14.0/bin/node
    Yarn: 1.22.18 - /usr/bin/yarn
    npm: 8.3.1 - ~/.nvm/versions/node/v16.14.0/bin/npm
  Browsers:
    Chrome: 101.0.4951.54
    Firefox: 100.0
  npmPackages:
    vitest: ^0.10.4 => 0.10.4 

Used Package Manager

npm

Validations

@sheremet-va
Copy link
Member

sheremet-va commented Jun 15, 2022

I think this might be a problem with how we handle Errors. Vitest needs to serialize them. To do so we clone its properties - this is when your error happens. We are cloning error here, if someone wants to fix this:

// https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm

@Tchoupinax
Copy link

Hello,
I got the same issue for several tests, one exemple

Error: Failed to fully serialize error: Method get Set.prototype.size called on incompatible receiver #<Set>
Inner error message: Validation error

vitest : 0.15.1
node : v16.15.1

@sheremet-va sheremet-va added bug good first issue Good for newcomers labels Jun 17, 2022
@benbender
Copy link

benbender commented Jul 25, 2022

I'm seeing the same error when using vitest, https://github.com/capricorn86/happy-dom/ & https://github.com/testing-library/jest-dom.

I thought this is an issue in happy-dom, but it may be better resolved here.

Related: capricorn86/happy-dom#544 & capricorn86/happy-dom#545

Repro: https://github.com/benbender/happy-dom-repro-544

@ChrisTowles
Copy link
Contributor

I tried to recreate this issue without any luck, not all the required files are listed so its not clear.

image

Edit on StackBlitz ⚡️

And repo at
https://github.com/ChrisTowles/vitest-dev-vitest-fckmry

@hnrq
Copy link

hnrq commented Aug 27, 2022

I've been getting this error everywhere when using happy-dom with vitest. jsdom works smoothly on the other hand

@sheremet-va
Copy link
Member

Fixed with #1921

@hnrq
Copy link

hnrq commented Aug 29, 2022

@sheremet-va any guess on when the next release will be out? 🥺

@github-actions github-actions bot locked and limited conversation to collaborators Jun 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

6 participants