未定义的属性测试 Lit typescript Web 组件

问题描述 投票:0回答:2

我最近将一个lit web组件转换为Typescript,似乎无法弄清楚为什么我的测试现在失败了..在转换之前一切都工作正常。

这些是我的测试依赖项:

"@open-wc/testing": "^3.1.2",
"@web/dev-server-esbuild": "^0.2.16",
"@web/test-runner": "^0.13.27"

所以我在

"test": "web-test-runner",
中使用以下配置运行
web-test-runner.config.mjs
(使用 tsc 转译代码也遇到了相同的错误):

import { esbuildPlugin } from '@web/dev-server-esbuild';

const filteredLogs = ['Running in dev mode', 'Lit is in dev mode'];

export default /** @type {import("@web/test-runner").TestRunnerConfig} */ ({
  files: 'lib/**/*.test.ts',
  nodeResolve: {
    exportConditions: ['browser', 'development'],
  },
  plugins: [esbuildPlugin({ ts: true })],
  filterBrowserLogs(log) {
    for (const arg of log.args) {
      if (typeof arg === 'string' && filteredLogs.some(l => arg.includes(l))) {
        return false;
      }
    }
    return true;
  }
});

并收到此错误:

components: > web-test-runner
components: Chrome: |██████████████████████████████| 0/1 test files | 0 passed, 0 failed
components: Running tests...
lib/MyElement/index.test.ts:
components:  ❌ MyElement > has a default title "World" and count 0
components:       AssertionError: expected undefined to equal 'World'
components:         at o.<anonymous> (lib/MyElement/index.test.ts:11:23)
components: Chrome: |██████████████████████████████| 1/1 test files | 0 passed, 1 failed
components: Finished running tests in 2.7s with 1 failed tests.
components: npm ERR! code ELIFECYCLE
components: npm ERR! errno 1
components: npm ERR! [email protected] test: `web-test-runner`
components: npm ERR! Exit status 1
components: npm ERR! 
components: npm ERR! Failed at the [email protected] test script.
components: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
components: npm ERR! A complete log of this run can be found in:
components: npm ERR!     /Users/shawn/.npm/_logs/2022-03-21T22_11_54_084Z-debug.log
lerna ERR! npm run test exited 1 in 'components'

这是组件代码:

import {LitElement, html, css} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';

@customElement('my-element')
 export class MyElement extends LitElement {
   static styles = css`
     :host {
       display: block;
       border: solid 1px gray;
       padding: 16px;
       max-width: 800px;
     }
   `;

   @property() name: string = 'World';

   @state() count: number = 0;

   _onClick() {
    this.count++;
    this.dispatchEvent(new CustomEvent('count-changed'));
  }

  sayHello(name: string) {
    return `Hello, ${name}`;
  }
 
  render() {
    return html`
      <h1>${this.sayHello(this.name)}!</h1>
      <button @click=${this._onClick} part="button">
        Click Count: ${this.count}
      </button>
      <slot></slot>
    `;
  }
 }

最后是测试代码:

import { html, fixture, expect } from '@open-wc/testing';

import { MyElement } from '.';

describe('MyElement', () => {
  it('has a default title "World" and count 0', async () => {
    const el = await fixture<MyElement>(html`
      <my-element></my-element>
    `);

    expect(el.name).to.equal('World');
    expect(el.count).to.equal(0);
  });
});

所以我相信这与转译打字稿有关,但我还没有成功地找出它到底是什么。有人注意到任何错误会导致这些属性现在未定义吗?

编辑:

这是原始的 JS 实现,以显示它与 TS 之间的差异。

import {LitElement, html, css} from 'lit';

 export class MyElement extends LitElement {
   static get styles() {
     return css`
       :host {
         display: block;
         border: solid 1px gray;
         padding: 16px;
         max-width: 800px;
       }
     `;
   }
 
   static get properties() {
     return {
       name: {type: String},
       count: {type: Number},
     };
   }
 
   constructor() {
     super();
     this.name = 'World';
     this.count = 0;
   }
 
   render() {
     return html`
       <h1>${this.sayHello(this.name)}!</h1>
       <button @click=${this._onClick} part="button">
         Click Count: ${this.count}
       </button>
       <slot></slot>
     `;
   }
 
   _onClick() {
     this.count++;
     this.dispatchEvent(new CustomEvent('count-changed'));
   }

   sayHello(name) {
     return `Hello, ${name}`;
   }
 }
 
 window.customElements.define('my-element', MyElement);
javascript typescript testing web-component lit
2个回答
1
投票

问题是您在测试文件中没有使用

MyElement
的实例,而仅使用其类型和标签。因此编译过程会抛出 import 语句
import { MyElement } from '.';
。如果您使用 tsc 编译测试文件,您会发现
.js
输出中缺少导入语句。

通过在测试中导入整个文件来修复它:

import './index.js';

注意: 在 lit-element-starter-ts 存储库的测试文件中(在 here 找到它),这种情况没有出现,因为他们在第一个测试用例中使用了 Element 的实例,因此名为 import不会被 tsc/esbuild 删除:

  import {MyElement} from '../my-element.js';

  // ...

  test('is defined', () => {
    const el = document.createElement('my-element');
    assert.instanceOf(el, MyElement);
  });

0
投票

你可以尝试一下吗

@property({type: String}) name = 'World';

https://lit.dev/docs/api/decorators/#property

© www.soinside.com 2019 - 2024. All rights reserved.