Home » Javascript » Unit Testing JS DMP, am I writing this right?

Unit Testing JS DMP, am I writing this right?

Posted by: admin November 1, 2017 Leave a comment

Questions:

So I am working on building a component library and have structured it so it looks like this structure wise

app
|---components
 |-------element
   |----element.hbs
   |----_element.scss
   |----element.js

In the actual JS I’m trying to use DMP (not sure if I have it written right, if not please feel free to correct, still trying to wrap head around the different patterns)

element.js

import $ from 'jquery';
import VARIABLE from 'ajsfile.js';

let Element = ( function() {
  const _private = {
    cacheDom: () => {
      _private.$element = $( '.js-element' );
      _private.$trigger = $( '.js-element__trigger' );
      _private.$target = $( '.js-element__target' );
      _private.$icon = $( '.js-element__icon' );
    },

    bindEvents: () => {
      _private.$trigger.on( 'click', function( e ) {
        e.preventDefault();

        _private.toggleTarget( $( this ) );
      });
    },

    preRender: () => {
      _private.$trigger.attr( 'aria-expanded', 'false' );
      _private.$target.slideUp( 0 );
    },

    toggleTarget: ( $thisTrigger ) => {
      let $thisParent = $thisTrigger.closest( _private.$element );
      let $thisTarget = $thisParent.find( _private.$target );
      let $thisIcon = $thisParent.find( _private.$icon );

      $thisTrigger
        .toggleClass( 'is-expanded' )
        .attr( 'aria-expanded', ( i, attr ) => {
          return attr == 'true' ? 'false' : 'true';
        });

      $thisTarget.slideToggle( VARIABLE );

      $thisIcon.toggleClass( 'is-rotated' );
    },

    init: () => {
      _private.cacheDom();
      _private.bindEvents();
      _private.preRender();
    }
  };

  /* test-code */
  const api = {
    __test: _private
  };

  return api;
  /* end-test-code */

  const _public = {
    preRender: _private.preRender,
    toggleTarget: _private.toggleTarget,
    init: _private.init
  };

  return _public;
})();

module.exports = Element;

The code block with the comment is actually removed when building, was reading about private unit testing from here but ESLint is returning an error: Unreachable code.

When I change the _public to be this it works, well it doesn’t error out:

const _public = {
  preRender: _private.preRender,
  toggleTarget: _private.toggleTarget,
  init: _private.init,

  /* test-code */
  __test: _private
  /* end-test-code */
};

The test ( the expect part I don’t run both, either one I run I get an error ):

import Element from './element.js';

describe( 'Element', function() {
  beforeEach( function() {
    this.element = Element;
  });

  it( 'should display closed', function() {
    console.log( this.element.__test );

    expect( this.element.toggleTarget ).toHaveClass( '.is-expanded' );
    // or
    expect( this.element.__test.toggleTarget ).toHaveClass( '.is-expanded' );
    // or
    expect( this.element.__test.toggleTarget( '.aclass' ) ).toHaveClass( '.is-expanded' );
  });
});

In console I see:

LOG: function toggleTarget($thisTrigger) { ... }
PhantomJS 2.1.1 (Mac OS X 0.0.0) Element should display closed FAILED
    Expected Function to have class '.is-expanded'.
    test-context.js:10507:61
    [email protected]://localhost:9876/context.js:162:17
    TypeError: undefined is not a constructor (evaluating    '$thisTrigger.closest(_private.$element)') thrown
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.002 secs / 0.003 secs)

Am I doing something wrong or is it because there really isn’t anything to test in this scenario since it’s mostly DOM stuff?

Or am I just thinking about this all wrong?

Any help would be appreciated as I’m still new to this mindset

Answers: