Question

Je suis unité de tester un peu de JavaScript avec Jasmine et je souhaite espionner (maquette) un élément du DOM qui est accessible par un sélecteur jQuery.

Ma spécification est:

it("should be able to mock DOM call", function() {

    spyOn($("#Something"), 'val').andReturn("bar");

    result = $("#Something").val();

    expect(result).toEqual("bar");

});

Dans mon specrunner.html je:

<input type="hidden" id="Something" value="foo" />

Malheureusement, la spécification échoue avec:

devrait être en mesure d'appel DOM maquette attendu 'foo' à égale 'bar'.

Était-ce utile?

La solution

Cette ligne est erroné:

spyOn($("#Something"), 'val').andReturn("bar");

La fonction spyOn Jasmine attend deux paramètres. Le premier est un objet existant. Le second est un nom de fonction en tant que chaîne. Vous passez correctement dans le nom de la fonction comme une chaîne ( « val ») mais vous n'êtes pas de passage dans un objet existant comme premier paramètre.

$("#Something")

... n'est pas un objet existant. Elle est le résultat (la valeur de retour) d'un sélecteur jQuery. Plus précisément, elle retourne un objet jQuery représentant les noeuds appariés -. Un peu comme un tableau de résultats

$

... est un objet existant.

$.fn

... est un objet existant.

$("#Something")

... pas un objet existant -. Il est le résultat d'un sélecteur jQuery

Cela fonctionne:

it("should be able to mock DOM call", function () {
    //spyOn($.fn, "val").andReturn("bar"); //pre-jasmine 2.0 syntax
    spyOn($.fn, "val").and.returnValue("bar"); //Jasmine 2.0 Syntax
    var result = $("#Something").val();
    expect(result).toEqual("bar");
});

Autres conseils

On dirait que j'ai trouvé une bonne solution

    it "should open past statuses", ->
      # We can't use $('.past') here cause each time $('.past') called it returns different objects
      # so we need to store spy in variable
      showSpy = spyOn($.fn, 'show')
      # do the stuff
      $('.show-past').click()
      # then check if 'show' action was called
      expect($.fn.show).toHaveBeenCalled()
      # and if it realy our object
      expect(showSpy.mostRecentCall.object.selector).toEqual('.past')

Ce ne repose pas sur votre code, mais j'espère que ce quelqu'un peut aide. Et, oui, par exemple dans coffeescript.

Le problème est que les deux appels à $ retour deux nœuds enveloppés de jQuery différents.

Cela devrait fonctionner:

it("should be able to mock DOM call", function(){

  // var node = $("Something");
  // spyOn(node, 'val').andReturn('bar');

  // expect(node.val()).toEqual('bar');
  var node = $("Something");
  spyOn(node, 'val').and.returnValue('bar');

  expect(node.val()).toEqual('bar');
});

La prochaine fois, l'aide est plus répandue sur la liste de diffusion Jasmine:. Jasmine-js@googlegroups.com

Vous pouvez créer votre propre élément DOM faux et puis utilisez $ ( '# elementid') [0] comme d'habitude

addFakeElementWithId = function (elementId) {
      var fake = document.createElement("div");
      fake.setAttribute("id", elementId);
      document.body.appendChild(fake);
   };

I wrote a helper-function, which accepts an array of id/value-pairs.

var jasminTestHelper = {
    spyOnValAndFake : function(obj) {
        var i, j;
        spyOn($.fn, 'val').andCallFake(function() {
            for ( i = 0, j = obj.length; i < j; i++) {
                if (this.selector === '#' + obj[i][0]) {
                    return obj[i][1];
                }
            }
        })
    }
}

Each pair tells the faker-function for which id, which value should be returned if the jQuery-val()-function is called with the id-selector. It is used like this:

jasminTestHelper.spyOnValAndFake([["id1", "value1"], ["id2", "value2"]]);

If $('#id1').val() is called in your function under test, the fake-function returns value1, if $('#id2').val() is called it returns value2. So you don't need to fiddle with the DOM, you just mock the jQuery-val()-function and simulate return-values. Other jQuery-functions could probably mocked the same way.

I think there is a change in my jasmine version (2.0.3), hence the solution by Alex York didn't work as is, but definitely gave me a path. So here is the working spec jquery code which is to be tested

$('someSelector').data('someAttribute').enable();

here is the jasmine spec part of it

var mockJqueryObject = { enable:function(){},disable:function(){}};
//this mocks the .data('someAttribute') in above code.
spyOn($.fn, "data").and.returnValue(mockSelectBoxObject); 

A more granular spec could use another level of mock as

spyOn(mockJqueryObject,"enable")
spyOn(mockJqueryObject,"disable")
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top