Search code examples
unit-testingreactjsclojurescriptjestjsreagent

Clojurescript/Reagent Unit testing component output and behaviour


We used react for about one year now, with immutable data, very impressive. We now want to move to Clojurescript/Reagent, but we need a very good way to test our code. For components this is what we did:

  1. Test the output of the component, depending on the props we sent:
  2. Test that the component invokes the right functions and with the right parameters when an event like click occurs

For 1 it would be like:

function renderFFC(filters, search_criterias)
{
    return TestUtils.renderIntoDocument(React.createElement(FilterIntervalNumberComponent,{filter:filters, search_criteria:search_criterias}));
}

describe("IN", function(){
    it("should render search criteria - interval", function() {
        var criterias = {};
        var ffc = renderFFC(filter, criterias);
        expect(ffc.refs[0].getDOMNode().value).toBeNull();
        expect(ffc.refs[1].getDOMNode().value).toBeNull();
     });

For 2 it would be something like:

describe("OUT", function(){
    it("should change the values, then click - boolean ", function() {
        //mock function
        set_criteria_and_search = jest.genMockFunction();

        var fbc = renderFBC(filter, {});

        React.addons.TestUtils.Simulate.change(fbc.refs.yes.getDOMNode(),{nativeEvent: {target: {value: true}}});

        expect(controller.set_criteria_and_search.mock.calls)
          .toEqual(
                    [['taxes_applied',{'taxes_applied':[{value:"1"}]}]]
                );
     });

We used facebook Jest for the tests.

How do I dothe same thing in Clojurescript with Reagent, preferably having the tests automatically run?


Solution

  • Testing reagent components:

    Test the component output. For a component:

     (defn weather-component [city temp country]
      [:div#weather
        [:h2#city {:on-click #(do-something 101)} city ]
        [:h3#temp temp]
        [:h3#contry country]])
    

    The test:

     (deftest weather-component-test-in
      ;;WHEN render component in test
      (let [comp (r/render-component [w/weather-component "Paris" 12]
                                 (. js/document (getElementById "test")))]
        ;;ASSERT
        (is (= (d/html (sel1 :#city)) "Paris"))
        (is (= (d/html (sel1 :#temp)) "12"))))
    

    Test that the component invokes the right functions and with the right parameters when an event like click occurs

    (deftest weather-component-test-out 
     (let [comp (r/render-component [w/weather-component "London" 0]
                                 (. js/document (getElementById "test"))) 
        expected-invocations (atom [])] 
        (with-redefs [weather-app.core/do-something #(swap! expected-invocations conj %)] 
          (sim/click (sel1 :#city) {})
          (is (=[101] @expected-invocations)))))
    

    To manipulate the dom and simulate events:

    [cljs-react-test "0.1.3-SNAPSHOT"] and dommy (d/...)