Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to unit test handlers #437

Closed
ryanflorence opened this issue Oct 29, 2014 · 30 comments
Closed

How to unit test handlers #437

ryanflorence opened this issue Oct 29, 2014 · 30 comments

Comments

@ryanflorence
Copy link
Member

https://gist.github.com/rpflorence/1f72da0cd9e507ebec29

Until the new API shows up, this works out pretty great.

@OscarGodson
Copy link

Made a comment on the gist. It's missing the merge function so I copy pasta'd one.

Seems to be working, but looks as though its stripping all methods from the component I'm testing. I assume its something to do with either the render or TestWrapper(props).

So If I have a Foo React class and Foo has a method bar() on it, when I do:

var foo = TestUtils.renderIntoDocument(makeStubbedDescriptor(Foo, {}));

Now Foo.bar is undefined whereas removing the makeStubbedDescriptor function from the renderIntoDocument call makes bar() exist again.

I'm trying to play around with the right way to render this with the existing Class' methods and stuff, but any guidance would be incredibly helpful.

@an1lam
Copy link

an1lam commented Nov 11, 2014

I'm also having issues getting Jest to deal with the react-router components. I tried the makeStubbedDescriptor method, as displayed below:

/** @jsx React.DOM */
jest.dontMock('jquery');
jest.dontMock('../test_helpers.jsx');
jest.dontMock('../js/components/CategoryPage.jsx');

describe('Category Page', function() {
  var React = require('react/addons');
  var TestUtils = React.addons.TestUtils;
  var helpers = require('../test_helpers.jsx');
  var makeStubbedDescriptor = helpers.makeStubbedDescriptor;
  var CategoryPage = require('../js/components/CategoryPage.jsx');


  it('renders into the page correctly', function() {
    // Render the CategoryPage into the document
    var TestCategoryPage = makeStubbedDescriptor(CategoryPage, {});
    var page = TestUtils.renderIntoDocument(TestCategoryPage);

    expect($.ajax).toBeCalled();
    expect(div).toBeDefined();
  });
});

And getting the following error:

● Category Page › it renders into the page correctly
   - Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

@OscarGodson
Copy link

Yeah, fwiw, I spent quite a few hours on this with 0 luck. It kinda sucks because Ive been unable to test any of the code we're working on. :\

@ryanflorence
Copy link
Member Author

We're going for a release this week with the new API that makes testing
much more straightforward.

We've got several apps now using the router and we don't commit code
without tests. I feel the pain, have worked around it, and am passionate
about simple testing.

On Tuesday, November 11, 2014, Oscar Godson notifications@github.com
wrote:

Yeah, fwiw, I spent quite a few hours on this with 0 luck. It kinda sucks
because Ive been unable to test any of the code we're working on. :\


Reply to this email directly or view it on GitHub
#437 (comment).

@an1lam
Copy link

an1lam commented Nov 12, 2014

Thanks you so much. My team is really looking forward to this. We look forward to the announcement / release!

@OscarGodson
Copy link

thanks @rpflorence! Since this ticket is closed, is there anyway you could just comment on this ticket when its released so I can get notified? Id like to implement the update once its done :)

@ryanflorence
Copy link
Member Author

Yep :)

On Wednesday, November 12, 2014, Oscar Godson notifications@github.com
wrote:

thanks @rpflorence https://github.com/rpflorence! Since this ticket is
closed, is there anyway you could just comment on this ticket when its
released so I can get notified? Id like to implement the update once its
done :)


Reply to this email directly or view it on GitHub
#437 (comment).

@OscarGodson
Copy link

Any update on this?

@ryanzec
Copy link

ryanzec commented Dec 13, 2014

I am still getting the same error as #453 (I assume 0.11.x was suppose to fix this).

@ryanzec
Copy link

ryanzec commented Dec 13, 2014

Well I did finally figure out how to get tests working without huge hacks. This test file : https://github.com/rackt/react-router/blob/master/modules/components/__tests__/Link-test.js : gave me the best insight on how to structure my tests.

@OscarGodson
Copy link

@ryanzec could you post the setup code and an example unit test?

@ryanzec
Copy link

ryanzec commented Dec 13, 2014

@OscarGodson well my setup is using Mocha to run the tests. I have a react seed project that has the test setup:

Test Helper: https://github.com/ryanzec/react-seed/blob/master/test/test-helper.js#L31-L47
Test Example: https://github.com/ryanzec/react-seed/blob/master/test/specs/components/desktop/prevent-double-click.component.spec.jsx

I think that helper method should handle a lot of use cases and most of the time I expect to be test 1 component with 1 route in my unit tests but I am sure as I build out my application, i'll be making tweaks to the helper method or even added more.

@OscarGodson
Copy link

@ryanzec you rock, thank you!

@dmwyatt
Copy link

dmwyatt commented Dec 19, 2014

We're going for a release this week with the new API that makes testing
much more straightforward.

@rpflorence Did this ever happen?

@mjackson
Copy link
Member

@dmwyatt Yes, it did. See the part about testing in https://github.com/rackt/react-router/wiki/Announcements

@dmwyatt
Copy link

dmwyatt commented Dec 19, 2014

Ahh thanks. That page doesn't come up in googlin for stuff about
react-router testing.

On Fri Dec 19 2014 at 12:36:32 PM Michael Jackson notifications@github.com
wrote:

@dmwyatt https://github.com/dmwyatt Yes, it did. See the part about
testing in https://github.com/rackt/react-router/wiki/Announcements


Reply to this email directly or view it on GitHub
#437 (comment).

@mjackson
Copy link
Member

There are also quite a few good examples in our own tests. Just look for
the tests directories inside the modules directory.

Michael Jackson
@mjackson

On Fri, Dec 19, 2014 at 10:41 AM, Dustin Wyatt notifications@github.com
wrote:

Ahh thanks. That page doesn't come up in googlin for stuff about
react-router testing.

On Fri Dec 19 2014 at 12:36:32 PM Michael Jackson <
notifications@github.com>
wrote:

@dmwyatt https://github.com/dmwyatt Yes, it did. See the part about
testing in https://github.com/rackt/react-router/wiki/Announcements


Reply to this email directly or view it on GitHub
#437 (comment).


Reply to this email directly or view it on GitHub
#437 (comment).

@azaharakis
Copy link

Hi the above gist, is 404ing, was hoping it would have some answers to my problem if it's still relevant. I'm having trouble understanding how one can unit test routeHandlers. In my case I have setup an app which is quite similar to the async data example in this repo, my handlers are very basic injecting async data into a another react component.
In my test I just want to verify that the routeHandler calls the correct react component with mock data from the statics fetchData method.
I'm using rewire to attempt to stub the react subcomponent in the handler but it still calls the actual sub component. Using rewire with my other components not going through the react-router seems to work as expected.

@fredrick
Copy link

@azaharakis Here is a basic snippet of a TestContext provider that is based off the above gist. Hopefully this helps: https://gist.github.com/wayoutmind/76e17f07409be07ffdcb

@azaharakis
Copy link

@wayoutmind, that's something I was after however, the problem still remains if I need to stub out a subcomponent. I've modeled what you have supplied to something I'm trying to do:
https://gist.github.com/azaharakis/db4cc200de559efa34e1
If I render App directly all is ok and the AppSubComponent is stubbed.
However the process of going through react router seems to require or load the handler without the stubbed methods, and actually calls the subcomponent.

@azaharakis
Copy link

Actually, the above method seems to work... Nothing to see here... Thanks for your help! I'll leave it up incase it helps anyone else.

@adjavaherian
Copy link

For people that are still having issues with testing React-Router based components in their own project. I've forked https://github.com/danvk/mocha-react and utilized the solution by @wayoutmind to provide test context to complicated components. This suite uses Mocha instead of Jest and allows you to have a lot more flexibility with stubs, mocks, spies. https://github.com/adjavaherian/mocha-react

@gregpalaci
Copy link

Getting weird errors with the TestLocation recommended way to use the router to test.
Keep getting - TypeError: Cannot call a class as a function
and I isolated it to TestLocation as a param in Router.run as the issue.

    TestLocation.history = ['/congratulations/id-1']
    Router.run routes,TestLocation.history, (Handler) ->
        TestUtils.renderIntoDocument(<Handler />)

@kellyrmilligan
Copy link
Contributor

@gregbenner did you ever get this worked out? i'm just starting out on getting unit tests working again with the new recommended way

@kellyrmilligan
Copy link
Contributor

is memory history now the preferred way?

@fredrick
Copy link

@kellyrmilligan @gregbenner You'll need to construct the TestLocation in newer versions of react-router instead of setting history:

new TestLocation(['/test'])

@fredrick
Copy link

I've updated my gist to show this: https://gist.github.com/wayoutmind/76e17f07409be07ffdcb

@gregpalaci
Copy link

I'd also recommend not using Jest, it's really terrible. It's super slow.. depends on old versions of Node.

This article has some tips for setting up testing with React
https://medium.com/about-codecademy/testing-with-reactjs-at-codecademy-2aec88cc4e36

@kellyrmilligan
Copy link
Contributor

agreed. i'm using tape with karma and just tape straight up with node. trying out wayoutminds gist

@kellyrmilligan
Copy link
Contributor

i'm still hitting a bit of a brick wall here. does test location match the default route?

here's my config:

<Route name="app" path="/shows" handler={App}>
    <DefaultRoute handler={ShowsHomePage}/>
   <Route name="showsDetail" path=":slug" handler={ShowsDetailPage}/>
...other routes defined here...
  </Route>

I included my routes definition into the getcontext method, so it's as follows:

getRouterComponent: function(path, TargetComponent, state, data) {
    var component,
      div = document.createElement('div'),
      routes = routes;

    var location = new TestLocation([path]);

    Router.run(routes, location, function (Handler) {
      var mainComponent = React.render(<Handler state={state} data={data} />, div);

      component = TestUtils.findRenderedComponentWithType(mainComponent,
        TargetComponent);
    });

    return component;

  },

in the console, i'm getting:
Warning: No route matches path "/shows"

i can't get it to work with a route that has a param either. still no match. I feel like I need to include my routes, since in my handlers i'm using named routes in link components everywhere, so if I don't then I get an invariant violation.

any ideas?

@lock lock bot locked as resolved and limited conversation to collaborators Jan 23, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests