【问题标题】:Undefined property testing Lit typescript web component未定义的属性测试 Lit typescript web 组件
【发布时间】:2022-06-28 22:07:05
【问题描述】:

我最近将一个点亮的 Web 组件转换为 Typescript,但似乎无法弄清楚为什么我的测试现在失败了。在转换之前一切正常。

这些是我用于测试的依赖项:

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

所以我在web-test-runner.config.mjs 中使用以下配置运行"test": "web-test-runner",(使用 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! components@1.0.0 test: `web-test-runner`
components: npm ERR! Exit status 1
components: npm ERR! 
components: npm ERR! Failed at the components@1.0.0 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 实现,用于显示 this 和 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);

【问题讨论】:

  • 如果您能够解决此问题,请分享一下吗?我目前面临的情况完全相同。似乎夹具将标签放在 DOM 中,但 Lit Element 没有被实例化。我想知道夹具是否可以访问注册 Web 组件所需的 JavaScript 代码。 @肖恩

标签: javascript typescript testing web-component lit


【解决方案1】:

你可以试试

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

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

【讨论】:

  • 感谢您的快速回复!这似乎不起作用,仍然收到相同的错误消息。我什至尝试在类的构造函数中设置这两个值,但它们在测试中仍然未定义。很奇怪,this 好像读不出来了。
  • 嗯...使用构造函数时,您首先调用了super() 对吗?
  • 我确实做到了,我上传了原始的 JS 实现,所以我们也可以看到两者之间的差异。
【解决方案2】:

问题是您没有使用MyElement 的实例,而只使用了它的类型和标签。因此编译过程将抛出导入语句import { MyElement } from '.';。如果您使用 tsc 编译您的测试文件,您会看到 .js-output 中缺少 import 语句。

通过导入整个文件来修复它:

import './index.js';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-31
    • 2022-11-03
    • 2012-12-29
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2021-03-16
    相关资源
    最近更新 更多