2012-08-22 12 views
7

Como se ve en este jsFiddle, tengo una función 'init' que configura un botón para que al hacer clic se abre un diálogo de progreso y emite una llamada Ajax. Quiero unidad de prueba este código JavaScript (usando QUnit), y comprobar los siguientes casos:¿Cómo pruebo la unidad de esta función de JavaScript, incluida la burla de la llamada Ajax?

  1. Ajax llamada se realiza correctamente
  2. Ajax llamada falla

necesito para burlarse a cabo al menos la llamada Ajax y la llamada al window.open, y otras llamadas estoy seguro, dependiendo de la implementación de la prueba unitaria.

¿Cómo puedo escribir pruebas de unidad de QUnit para mi código que prueba estos dos escenarios?

EDIT: El código que necesita ser probado:

var statusmod = (function() { 
    var spinner = $("#spinner"); 

    var init = function(id) { 
     var progressDialog = $("#progressdialog-content").dialog({ 
      autoOpen: false, 
      title: "Launching Status Page" 
     }); 
     var errorDialog = $("#errordialog-content").dialog({ 
      autoOpen: false, 
      modal: true, 
      buttons: { 
       "OK": function() { 
        $(this).dialog("close"); 
       } 
      } 
     }); 

     var btn = $("#button-status"); 
     btn.button().click(function() { 
      spinner.show(); 

      progressDialog.dialog("open"); 

      var url = $.validator.format("/api/binid/?id={0}", id); 
      // Call Web service to get binary ID 
      $.ajax({ 
       url: url, 
       dataType: "json" 
      }).done(function(data) { 
       window.open($.validator.format("http://status/?Page=Status&Id={0}", data.Id), target = "_newtab"); 
      }).fail(function(jqXHR, msg, errorThrown) { 
       errorDialog.dialog("open"); 
      }).always(function() { 
       progressDialog.dialog("close"); 
      }); 

      return false; 
     }); 
    }; 

    return { 
     init: init, 
     _spinner: spinner 
    }; 
}()); 
+1

Considere mockjax por burlarse de la llamada ajax, funciona como un encanto @rsplak – rsplak

+0

Podría por favor mostrar cómo ejecutar pruebas después de devoluciones de llamada de Ajax se han invocado? No puedo ver cómo, en este momento. – aknuds1

Respuesta

1

He escrito con éxito una prueba QUnit para el caso de éxito y otra para el caso de falla, como se puede ver en this jsFiddle. Utilicé Mockjax para falsificar respuestas Ajax y simular condiciones de éxito/fracaso. En particular, configuré las llamadas Ajax para que fueran sincrónicas, de modo que podía escribir pruebas sincrónicas, ya que tenía problemas para averiguar cómo ejecutar mis pruebas después de que se activaran las devoluciones de llamada asíncronas de Ajax.

También hago uso de la biblioteca Sinon.JS para falsificar dependencias y verificar que, p. los diálogos se inician correctamente.

El código de prueba de trabajo se incluye a continuación, consulte mi pregunta para la función bajo prueba (statusmod.init). Avísame si hay algo que crees que he omitido.

var dialogSpy = null; 
var windowSpy = null; 
var id = "srcId"; 
var binId = "binId"; 
var url = $.validator.format("/api/binid/?id={0}", id); 
var btnId = "#button-status"; 

module("Open status page", { 
    setup: function() { 
     // Allow us to run tests synchronously 
     $.ajaxSetup({ 
      async: false 
     }); 
     windowSpy = sinon.spy(window, "open"); 
     dialogSpy = sinon.spy(); 
     sinon.stub($.fn, "dialog", function() { 
      return { 
       "dialog": dialogSpy 
      }; 
     }); 

     statusmod.init(id); 
    }, 
    teardown: function() { 
     windowSpy.restore(); 
     $.fn.dialog.restore(); 
     $.mockjaxClear(); 
     // Remove click event handler for each test 
     $(btnId).unbind(); 
    } 
}); 

test("Successfully open status page", function() { 
    expect(4); 

    $.mockjax({ 
     url: url, 
     contentType: "text/json", 
     responseText: { 
      Id: binId 
     } 
    }); 

    var spinner = statusmod._spinner; 
    var spinnerSpy = sinon.spy(spinner, "show"); 

    $(btnId).click(); 

    ok(spinnerSpy.calledOnce, "Spinner shown"); 
    ok(dialogSpy.withArgs("open").calledOnce, "Dialog opened"); 
    ok(dialogSpy.withArgs("close").calledOnce, "Dialog closed"); 
    equal(windowSpy.lastCall.args[0], $.validator.format("http://status/?Page=Status&Id={0}", binId), "Window opened"); 
}); 

test("Binary ID not found on server", function() { 
    expect(3); 

    $.mockjax({ 
     url: url, 
     contentType: "text/json", 
     status: 404 
    }); 

    $(btnId).click(); 

    ok(dialogSpy.withArgs("open").calledTwice, "Dialogs opened"); 
    ok(dialogSpy.withArgs("close").calledOnce, "Progress dialog closed"); 
    ok(!windowSpy.called, "Window not launched"); 
}); 
0

En primer lugar, descargar e incluyen Mockjax.

A continuación, se burlan de sus llamadas ajax:

module("Mock Ajax", { 
    setup: function() { 
    /** this mocks the ajax call **/ 
    $.mockjax({ 
     url: 'yourUrl.php', 
     data: {'action': 'your', 
     'data': { 
      'that': 'you', 
      'send': 'here' 
     } 
     }, 
     responseText:'{"your": ["returned":"json"],"string"}' 
    }); 
    }); 
}); 

y entonces usted puede hacer su llamada AJAX en un caso de prueba:

test("Your testcase", function() { 
    $.ajax('yourUrl.php', 
    data: {'action': 'your', 
     'data': { 
     'that': 'you', 
     'send': 'here' 
    } 
    }, function(data) { 
     ok("do something with your data"); 
    }); 
}); 

Et voilà, que ha probado con éxito algo! Puede agregar parámetros adicionales a su llamada a mockjax (isTImeout, isError, etc.). La documentación se puede encontrar here.

Estos son los conceptos básicos, puede editarlos según sus necesidades utilizando la documentación, que es bastante completa.

+0

Gracias, pero esto realmente no resuelve mi problema. No quiero hacer una llamada simulada de Ajax en mi caso de prueba, quiero llamar a 'status.init', hacer clic en el botón y asegurarme de que la llamada Ajax se hace correctamente y que las devoluciones de llamada hechas/no contestadas/siempre hacen lo correcto cosa. Tengo una solución casi de trabajo al hackear el problema hoy, pero actualmente estoy atascado en un pequeño detalle en mockjax. – aknuds1

+0

En ese sentido, tal vez pueda responder mi pregunta específica sobre mockjax, ya que debería ser bastante simple. http://stackoverflow.com/questions/12093731/why-does-mockjax-return-an-altered-response-to-my-ajax-consumer – aknuds1

Cuestiones relacionadas