你好,我是JS的新手,可能是代码中的错误。
但是我不明白为什么getAttribute
不是函数。
测试:
test('TESTING', () => {
const filterNodes = [
<div key='1' value='foo' />,
<div key='2' value='bar' />
]
const filtersKeyValue = {
key: ['0', '1', '1', '3'],
value: ['foo', 'bar', 'toto', 'react']
}
expect(fillReportSpecFiltersWithValues(filterNodes, filtersKeyValue)).toBe()
})
代码:
export const fillReportSpecFiltersWithValues = (filterNodes, filtersKeyValue = {}) => {
for (const key in filtersKeyValue) {
const value = filtersKeyValue[key]
for (const filterNode of filterNodes) {
if (filterNode.getAttribute('key') === key) {
filterNode.setAttribute('value', value)
}
}
}
}
有什么建议值得赞赏吗?
答案 0 :(得分:1)
此代码
const filterNodes = [
<div key='1' value='foo' />,
<div key='2' value='bar' />
]
创建一组代表React节点的对象。在您调用ReactDOM.render()
之前,它们实际上并不是HTMLElement或DOM节点。
请考虑以下内容,以打印由JSX表达式表示的Object。它没有您要尝试调用的方法。您需要调整测试以查看对象确实具有或可能将JSX对象呈现给DOM的属性,然后然后将它们视为HTMLElement。
// JSX to construct an anchor with an href
const bar = "http://example.com";
const foo = <a href={bar}>anchor</a>;
// Prints the JSX Object definition
console.log(foo);
// This will actually populate the DOM with the JSX definition
const dom = ReactDOM.render(foo, document.getElementById("fizz"));
// The rendered DOM node
console.log(dom);
// The attribute pulled from the DOM node
console.log(dom.getAttribute("href"));
<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>
<div id="fizz"></div>
考虑到这一点,您的代码测试代码应该看起来更像这样,其中您通过map()
ReactDOM.render()
来使用JSX对象,以便它们成为HTMLElements:
test('TESTING', () => {
// Make someplace to put the elements that you want converted
const app = document.getElementById("foo");
// Map them through ReactDOM.render() to make elements
const filterNodes = [
<div key='1' value='foo' />,
<div key='2' value='bar' />
].map(n => ReactDOM.render(n, app));
// Sanity check
console.log(filterNodes);
const filtersKeyValue = {
key: ['0', '1', '1', '3'],
value: ['foo', 'bar', 'toto', 'react']
}
expect(fillReportSpecFiltersWithValues(filterNodes, filtersKeyValue)).toBe()
})
<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>
<div id="foo"></div>
答案 1 :(得分:1)
听起来你的工作就是测试fillReportSpecFiltersWithValues
。
它接受具有getAttribute
和setAttribute
属性的对象数组,以及代表键/值对的对象。
与其通过创建模拟的DOM元素进行测试,不如通过创建适当的模拟对象进行测试:
test('fillReportSpecFiltersWithValues', () => {
const filterNodes = [
{ getAttribute: () => '1', setAttribute: jest.fn() },
{ getAttribute: () => '2', setAttribute: jest.fn() },
{ getAttribute: () => '3', setAttribute: jest.fn() }
]
const filtersKeyValue = {
'1': 'foo',
'2': 'bar'
}
fillReportSpecFiltersWithValues(filterNodes, filtersKeyValue);
expect(filterNodes[0].setAttribute).toHaveBeenCalledWith('value', 'foo'); // Success!
expect(filterNodes[1].setAttribute).toHaveBeenCalledWith('value', 'bar'); // Success!
expect(filterNodes[2].setAttribute).not.toHaveBeenCalled(); // Success!
});