我正在使用TypeScript构建一个React应用程序。我使用React Testing Library进行组件测试。
假设您的表单很简单:
CTScaling ctScaling = ...
...
CTValAx ctValAx = ctPlotArea.addNewValAx();
ctValAx.addNewAxId().setVal(123457); //id of the val axis
ctScaling = ctValAx.addNewScaling();
ctScaling.addNewOrientation().setVal(STOrientation.MIN_MAX);
ctScaling.addNewMin().setVal(0.2);
ctScaling.addNewMax().setVal(0.7);
ctValAx.addNewDelete().setVal(false);
ctValAx.addNewAxPos().setVal(STAxPos.L);
ctValAx.addNewCrossAx().setVal(123456); //id of the cat axis
ctValAx.addNewCrosses().setVal(STCrosses.AUTO_ZERO); //this val axis crosses the cat axis at zero
ctValAx.addNewTickLblPos().setVal(STTickLblPos.NEXT_TO);
...
在this video中,Kent(库的创建者)展示了如何测试表单输入。测试看起来像这样:
import React from 'react'
function Login({onSubmit}) {
return (
<div>
<form
onSubmit={e => {
e.preventDefault()
const {username, password} = e.target.elements
onSubmit({
username: username.value,
password: password.value,
})
}}
>
<label htmlFor="username">Username</label>
<input id="username" />
<label htmlFor="password">Password</label>
<input id="password" type="password" />
<br />
<button type="submit">Submit</button>
</form>
</div>
)
}
export {Login}
问题在于他使用纯JavaScript做到了。当这样做
在他设置import React from 'react'
import {renderIntoDocument, cleanup} from 'react-testing-library'
import {Login} from '../login'
afterEach(cleanup)
test('calls onSubmit with username and password', () => {
const handleSubmit = jest.fn()
const {getByLabelText, getByText} = renderIntoDocument(
<Login onSubmit={handleSubmit} />,
)
getByLabelText(/username/i).value = 'chuck'
getByLabelText(/password/i).value = 'norris'
getByText(/submit/i).click()
expect(handleSubmit).toHaveBeenCalledTimes(1)
expect(handleSubmit).toHaveBeenCalledWith({
username: 'chuck',
password: 'norris',
})
})
的行中键入TypeScript会引发以下错误
.value
如何使用React Testing Library使用TypeScript测试此功能?您将如何设置输入的值?
答案 0 :(得分:7)
该库提供的类型将getByLabelText
的返回值键入为HTMLElement
。并非所有HTML元素都具有value
属性,只有HTMLInputElement
之类的属性。
getByLabelText
也没有通用类型,您可能无法通过该通用类型来影响输出类型,因此从本质上讲,您将需要不安全地将结果强制转换为类型HTMLInputElement
,否则您将需要构建一个帮助函数,该函数告诉TypeScript对象是否为正确的类型:
不安全的投射。您真正需要做的就是将对getByLabelText
的任何调用更新为具有value
属性的类型,以:
(getByLabelText(/username/i) as HTMLInputElement).value = 'chuck';
类型验证。此方法较为安全,因为您可以提供类型验证功能,该功能将导致TypeScript更新类型:
function isElementInput<T extends HTMLElement>(element: T): T is HTMLInputElement {
// Validate that element is actually an input
return element instanceof HTMLInputElement;
}
// Update your attempted value sets:
const elem = getByLabelText(/username/i);
if (isElementInput(elem)) {
elem.value = 'chuck';
} else {
// Handle failure here...
}