2010-12-20 11 views
13

? Estoy tratando de omitir/simular/anular una llamada de función durante la prueba que escribe un registro en un DB.¿Cómo puedo rescindir/simular una función en el espacio de nombres global javascript

function logit(msg) { 
    writeMessageToDb(msg); 
} 

function tryingToTestThisFunction(){ 
    var error = processSomething(); 
    if (error) { 
    logit(error); 
    } 
} 

me gustaría logit() para imprimir simplemente a la consola durante la prueba ... y haciendo un "isTesting()" if/else bloque dentro de la función logit() no es una opción.

Esto es posible sin incluir algún marco de burla adicional. Actualmente estoy usando JsTestDriver para pruebas de unidades y no he tenido la oportunidad de evaluar marcos de burla. Una solución ideal en este momento sería manejar esto sin otro marco.

Respuesta

3

En javascript, la última definición es la que prevalece.

así que simplemente redefina el método logit después de la primera definición.

function logit(msg) { 
    console.log(msg); 
} 

ejemplo: http://www.jsfiddle.net/gaby/UeeQZ/

1

puede simplemente reemplazar el método en el objeto ventana? En la consola de Chrome esto funciona

function test() {console.log('test')}; 
window.test(); 
6

utilizo Jazmín y Sinon.js (usando CoffeeScript), así es como me golpeo a cabo el método confirm() a, por ejemplo, acaba de vuelta verdad.

beforeEach -> 
    @confirmStub = sinon.stub(window, 'confirm') 
    @confirmStub.returns(true) 

afterEach -> 
    @confirmStub.restore() 
+2

Este caso es diferente como Window.confirm() no es una función global. –

1

simplemente reemplazar la función logit, esto se puede llamar en cualquier momento a más tardar se define logit.

(function(){ 
    //keep handle to original logit method. 
    var ol = logit; 

    //shorter lookup path for slice 
    var s = Array.prototype.slice; 

    //logit override 
    logit = function() { 
    //if in testing 
    if (typeof IsTesting == "function" && !!IsTesting()) { 
     //log the arguments 
     console.log.apply(console, s.call(arguments)); 
    } else { 
     //otherwise, call the original function. 
     ol.apply(this, s.call(arguments)) 
    } 
    } 
}());
+0

NOTA: puede especificar "msg" como parámetro y pasarlo directamente, el llamado (argumentos) con .aplicar en el método pasará todo, lo que funciona mejor para anulaciones de métodos como esta. – Tracker1

1

He estado trabajando exactamente en el mismo problema. Los desarrolladores me dieron una aplicación HTML5 para probar, así que por supuesto no puedo cambiar su código para probar. Decidí usar qunit y sinon, junto con sinon-qunit.

Para una prueba de la unidad newb to JavaScript como yo, me estaba volviendo loco con la documentación de sinon y varios ejemplos en la web, ya que la mayoría parece por un entorno implícito que no se menciona. El siguiente código es una página completa, por lo que espero que no quede nada por confusión.

La función a la que tengo que llamar es caller() y no puedo hacer nada con stubme() porque está en el código del desarrollador. Sin embargo, puedo agregar sinonstub() en mi código de prueba. Pero, ¿cómo lograr que funcione con sinon? La documentación de sinon realmente me confundió por un tiempo, pero a continuación está la solución simple. El objeto stub4stubme se puede usar para controlar la acción de stub y también para obtener información sobre lo que está sucediendo con las llamadas stub.

<!DOCTYPE html> 

<html lang="en" xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
    <meta charset="utf-8" /> 
    <title></title> 
    <link rel="stylesheet" href="qunit-1.12.0.css" type="text/css" media="screen" /> 
</head> 
<body> 
    <div id="qunit"></div> 
    <div id="qunit-fixture"></div> 
    <script src="sinon-1.7.3.js"></script> 
    <script src="qunit-1.12.0.js"></script> 
    <script src="sinon-qunit-0.8.0.js"></script> 
    <script> 

     // Dev code in another file 
     function stubme() { 
      return "stubme"; 
     } 

     function caller() { 
      return "caller " + stubme(); 
     } 
     // End of dev code 

     var sinonstub = function() { 
      return "u haz bin stubbed"; 
     }; 

     test("Stubbing global environments", function() { 
      equal(caller(), "caller stubme"); 

      var stub4stubme = this.stub(window, "stubme", sinonstub); 

      equal(caller(), "caller u haz bin stubbed"); 
      ok(stubme.called); 
     }); 

    </script> 
</body> 
</html> 
+0

Casi has enterado mi confusión. Sinon.stub (ventana, "stubme", sinonstub); ¿Por qué es "ventana" el nombre del objeto de nivel superior? Aquí está sucediendo algo sobre el entorno variable global, que en su ejemplo se llama ventana porque se ejecuta en una ventana. Pero el póster original podría estar en Node.js o ... ¿entonces sigue siendo "ventana"? –

0

Porque en Javascript no es solamente tiempo de ejecución vinculados, pero la última palabra gana vinculado, simplemente redeclare el método con el comportamiento que desea en su ensayo:

function yourTest(){ 
    oldImpl = logit; // better to use a setup. 
    logit = function(msg){ Console.log.apply(console, s.call(arguments));}; 
    // do you assertions: assert.... yada. 

    logit = oldImpl; // Do this to keep your test isolated from the others you'll be executing in this test run. Better to use a tear down. 
} 
Cuestiones relacionadas