React-Router: How to test the rendering href of a Link?
I have a React component that renders <Link/>
.
render: function () {
var record = this.props.record;
return (
<Link to="record.detail" params={{id:record.id}}>
<div>ID: {record.id}</div>
<div>Name: {record.name}</div>
<div>Status: {record.status}</div>
</Link>
);
}
I can easily get the rendered <a/>
, but I'm not sure how to check if the href is plotted correctly.
function mockRecordListItem(record) {
return stubRouterContext(require('./RecordListItem.jsx'), {record: record});
}
it('should handle click', function () {
let record = {id: 2, name: 'test', status: 'completed'};
var RecordListItem = mockRecordListItem(record);
let item = TestUtils.renderIntoDocument(<RecordListItem/>);
let a = TestUtils.findRenderedDOMComponentWithTag(item, 'a');
expect(a);
// TODO: inspect href?
expect(/* something */).to.equal('/records/2');
});
Notes: stubRouterContext is required in React-Router v0.13.3 to mock correctly <Link/>
.
Edit:
Thanks to Jordan for the suggestion a.getDOMNode().getAttribute('href')
. Unfortunately, when I run the test, the result is null
. I expect it has something to do with how stubRouterContext
ridiculed <Link/>
, but how to "fix" still TBD ...
source to share
Ok. It just took a while in stubRouterContext
which I already had.
The third constructor argument stubs
is what I needed to pass, overriding the default function makeHref
.
Working example:
function mockRecordListItem(record, stubs) {
return stubRouterContext(require('./RecordListItem.jsx'), {record: record}, stubs);
}
it('should handle click', function () {
let record = {id: 2, name: 'test', status: 'completed'};
let expectedRoute = '/records/2';
let RecordListItem = mockRecordListItem(record, {
makeHref: function () {
return expectedRoute;
}
});
let item = TestUtils.renderIntoDocument(<RecordListItem/>);
let a = TestUtils.findRenderedDOMComponentWithTag(item, 'a');
expect(a);
let href = a.getDOMNode().getAttribute('href');
expect(href).to.equal(expectedRoute);
});
It was right in front of me the whole time.
source to share
You can use a.getDOMNode()
to get a a
DOM node component and then use normal DOM node methods on it. In this case, it getAttribute('href')
will return the value of the attribute href
:
let a = TestUtils.findRenderedDOMComponentWithTag(item, 'a');
let domNode = a.getDOMNode();
expect(domNode.getAttribute('href')).to.equal('/records/2');
source to share
I am using clown and enzyme for testing. For the link from the route I am using the Memory Router from their official documentation https://reacttraining.com/react-router/web/guides/testing
I needed to check the href of the final built link. This is my suggestion:
MovieCard.js:
export function MovieCard(props) {
const { id, type } = props;
return (
<Link to={`/${type}/${id}`} className={css.card} />
)
};
MovieCard.test.js (I'm skipping imports here):
const id= 111;
const type= "movie";
test("constructs link for router", () => {
const wrapper = mount(
<MemoryRouter>
<MovieCard type={type} id={id}/>
</MemoryRouter>
);
expect(wrapper.find('[href="/movie/111"]').length).toBe(1);
});
source to share