Search code examples
javascriptjqueryqunit

Qunit data erased


Can someone explain why in the third console log the data is empty?

This is a shortened version of a problem I'm having with my tests. I'm noticing the absence of data in my test functions, inserted in "QUnit.test (...)". Some of the functions, triggered by events, use this data and errors are occurring.

An executable code can be found on JsBin

$(document).ready(function() {
  $("p").data("thedata", 1);
  console.log("First", $("p").data());
});

QUnit.config.autostart = false;
setTimeout(function() {
  QUnit.start();
  console.log("Second", $("p").data());
}, 1000);

setTimeout(function() {
  console.log("Third", $("p").data());
}, 2000);
<html>

<head>
  <meta charset="utf-8">
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
  <link href="http://code.jquery.com/qunit/qunit-2.1.1.css" rel="stylesheet" />
  <script src="http://code.jquery.com/qunit/qunit-2.1.1.js"></script>
</head>

<body>
  <div id="qunit"></div>
  <div id="qunit-fixture">
    <p>content</p>
  </div>
</body>

</html>


Solution

  • Okay, after seeing your JSBin I figured out what the issue is. Part of this is that in your code above you are not actually using QUnit at all (there are no tests), but the real issue is that the QUnit "fixtures" are reset after each test (intentionally). The first two work because QUnit must be considering that the first test, but the 2000 ms timeout for the third console log must happen after the "test", meaning the fixture is reset to its original HTML. Note that your add the data in JS, NOT in the HTML.

    So... here are your options: put the data in the actual HTML (<p data-thedata='1'>content</p>) or you can set up a proper QUnit test with a beforeEach hook (this is my preferred option). Here is the code for option two, and a working JSBin.

    $(document).ready(function() {
      console.log("First", $("p").data());
    });
    
    QUnit.config.autostart = false;
    
    QUnit.module('data', {
      beforeEach: function() {
        $("p").data("thedata", 1);
        console.log("before each", $("p").data());
      }
    });
    
    QUnit.test('data delay', function(assert) {
      let done = assert.async();
    
      setTimeout(function() {  
        console.log("Second", $("p").data());
      }, 1000);
    
      setTimeout(function() {
        console.log("Third", $("p").data());
        assert.ok($("p").data());
        assert.equal($("p").data().thedata, 1);
        done();
      }, 2000);
    });
    
    QUnit.start();