最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React-Router: How to test href of a rendered Link? - Stack Overflow

programmeradmin5浏览0评论

I have a React component that renders a <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 obtain the rendered <a/>, but I'm not sure how to test that the href was built properly.

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: The stubRouterContext is necessary in React-Router v0.13.3 to mock the <Link/> correctly.

Edit:

Thanks to Jordan for suggesting a.getDOMNode().getAttribute('href'). Unfortunately when I run the test, the result is null. I expect this has to do with the way stubRouterContext is mocking the <Link/>, but how to 'fix' is still TBD...

I have a React component that renders a <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 obtain the rendered <a/>, but I'm not sure how to test that the href was built properly.

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: The stubRouterContext is necessary in React-Router v0.13.3 to mock the <Link/> correctly.

Edit:

Thanks to Jordan for suggesting a.getDOMNode().getAttribute('href'). Unfortunately when I run the test, the result is null. I expect this has to do with the way stubRouterContext is mocking the <Link/>, but how to 'fix' is still TBD...

Share Improve this question edited May 23, 2017 at 12:33 CommunityBot 11 silver badge asked May 19, 2015 at 17:46 Jeff FairleyJeff Fairley 8,3147 gold badges47 silver badges57 bronze badges 1
  • Yeah. See my answer which is the accepted one. stackoverflow.com/a/30333190/317951 – Jeff Fairley Commented Dec 9, 2015 at 22:44
Add a comment  | 

3 Answers 3

Reset to default 8

I use jest and enzyme for testing. For Link from Route I use Memory Router from their official documentation https://reacttraining.com/react-router/web/guides/testing

I needed to check href of the final constructed 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 skip 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);
  });

Ok. This simply took some digging into the stubRouterContext that I already had.

The third constructor argument, stubs, is what I needed to pass in, overriding the default makeHref function.

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 there in front of me the whole time.

You can use a.getDOMNode() to get the a component's DOM node and then use regular DOM node methods on it. In this case, getAttribute('href') will return the value of the href attribute:

let a = TestUtils.findRenderedDOMComponentWithTag(item, 'a');
let domNode = a.getDOMNode();

expect(domNode.getAttribute('href')).to.equal('/records/2');
发布评论

评论列表(0)

  1. 暂无评论