我使用Stenicljs创建了一个单独的web组件库,并在React应用程序中使用它,在编写测试用例时意识到事件没有按预期工作。我试过模拟这个组件,但没能找到正确的方法。绝对需要一些帮助…!
模板组件:
import { Component, ComponentInterface, Element, Event, EventEmitter, h, Host, Prop } from '@stencil/core';
import { ButtonAppearance, ButtonSize, ButtonType } from '../types';
import classnames from 'classnames';
import { generateUniqueId } from '../../utils/utils';
@Component({
tag: 'stencil-button',
styleUrl: 'stencil-button.scss',
shadow: true,
})
export class StencilButton implements ComponentInterface {
@Element() el!: HTMLElement;
@Prop({ attribute: 'autofocus' }) autoFocus?: boolean;
@Prop({ mutable: true }) value: string;
@Prop() disabled?: boolean;
@Prop() name?: string;
@Prop() form?: string;
@Prop() stencilHidden?: boolean;
@Prop() type?: ButtonType = 'button';
@Prop() class: string;
@Prop() appearance: ButtonAppearance;
@Prop() size: ButtonSize;
@Prop() bold: boolean;
@Prop() stencilId: any;
@Prop() inLine: boolean;
private handleClick = (e: Event) => {
if (this.disabled) {
e.preventDefault();
e.stopPropagation();
}
const form = this.el.closest('form');
if (form) {
e.preventDefault();
const dummyButton = document.createElement('button');
dummyButton.type = this.type;
dummyButton.style.display = 'none';
dummyButton.name = 'dummy-button';
form.appendChild(dummyButton);
dummyButton.click();
dummyButton.remove();
}
};
@Event() stencilClick!: EventEmitter<void>;
private onHandle = e => {
this.stencilClick.emit(e);
};
private buttonId = `gt-button-${generateUniqueId()}`;
render () {
const isWrapper = this.appearance === 'wrapper';
const classList = classnames({
btn: true && !isWrapper,
[this.appearance]: this.appearance && !isWrapper,
[this.size]: this.size && !isWrapper,
[this.class]: this.class && !isWrapper,
bold: this.bold && !isWrapper,
wrapper: isWrapper,
stencilInline: this.inLine,
});
const hostStyles = classnames({
stencilInline: this.inLine
})
return (
<Host onClick={this.handleClick} class={hostStyles}>
<button
class={classList}
id={this.stencilId ? this.stencilId : this.buttonId}
onClick={this.onHandle}
autoFocus={this.autoFocus}
hidden={this.stencilHidden}
disabled={this.disabled}
name={this.name}
type={this.type}
form={this.form}
>
<slot></slot>
</button>
</Host>
);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
目前,我正在尝试模拟我的react应用程序中的Stencil按钮:
const App = () => {
const [btnvalue, setbtnvalue] = useState(0);
const increment = () => {
setbtnvalue(btnvalue + 1);
};
return (
<div>
<StencilButton onStencilClick={increment} data-testid='click-btn'>
{btnvalue}
</StencilButton >
</div>
);
};
下面是我的测试用例:
describe('counter test cases', () => {
it('updated counter on click', () => {
const clickBtn = getByTestId('click-btn');
fireEvent.click(clickBtn);
console.log(clickBtn.textContent);
expect(clickBtn.textContent).toBe('1');
});
});
我最近也遇到了类似的问题。发现这个堆栈溢出,希望得到帮助。不确定你是否在技术上有同样的问题,我是,但我是解锁感谢帮助在Stencil slack帐户。
在我的例子中,我需要在我的测试文件中注册组件,就像我在索引中所做的那样。
的例子:
defineCustomElements(window);
然后我只是等待组件有一个水合类:
await waitFor(() => {
expect(filter).toHaveClass('hydrated');
});
终于找到了解决办法。
import StencilButton from 'stencil-components';
jest.mock('stencil-components', () => ({
StencilButton: (props) => {
return (
<button
{...props}
/>
);
},
}));