unit testing - Ejemplo de Squire.js con Jasmine y RequireJS
unit-testing squirejs (1)
Esta es una buena configuración para insertar módulos con dependencias simuladas en las pruebas. Este es un ejemplo de principio a fin para que alguien comience, salta al final si solo quieres ver la especificación.
Estructura de la carpeta:
Jasmine
|-lib
||-jasmine -- Contains all the Jasmine files
|||-boot.js
|||-jasmine-html.js
|||-jasmine.js
|||-jasmine.css
|||-jasmine_favicon.png
|||-...
|-spec -- Spec files go here
||-hello-spec.js
|SpecRunner.html
|SpecRunner.js
|squire.js
Scripts
|knockout.js
|require.js
|jquery.js
App
|-hello.js
|-foo.js
En el momento de su pregunta, Jasmine 1.3 era la última versión. Desde entonces se lanzó 2.0 y contiene algunas mejoras asíncronas. Ambas versiones están incluidas aquí, 1.3 está comentada.
SpecRunner.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine/jasmine.css">
</head>
<body>
<!-- Load RequireJS & the testsuite -->
<script src="../Scripts/require.js" data-main="SpecRunner.js" type="text/javascript" ></script>
</body>
</html>
SpecRunner.js:
Esta pregunta ¿Realmente no funciona Jasmine 2.0 con require.js? Fue útil para poner esto en marcha.
(function () {
''use strict'';
// Configure RequireJS to shim Jasmine
requirejs.config({
baseUrl: "../App",
paths: {
''jasmine'' : ''../Jasmine/lib/jasmine/jasmine'',
''jasmine-html'': ''../Jasmine/lib/jasmine/jasmine-html'',
''boot'': ''../Jasmine/lib/jasmine/boot'', // This is not present in Jasmine 1.3
''spec'' : ''../Jasmine/spec'',
''squire'': ''../Jasmine/squire'',
''knockout'': ''../Scripts/knockout-2.3.0'',
''jquery'': ''../Scripts/jquery-1.10.2'' // This only used in the Jasmine 1.3 case.
},
shim: {
''jasmine'': {
exports: ''jasmine''
},
''jasmine-html'': {
deps: [''jasmine''],
exports: ''jasmine''
},
''boot'': {
deps: [''jasmine'', ''jasmine-html''],
exports: ''jasmine''
},
"squire": {
exports: "squire"
}
}
});
// Define all of your specs here. These are RequireJS modules.
var specs = [
''spec/hello-spec''
];
// Load Jasmine - This will still create all of the normal Jasmine browser globals unless `boot.js` is re-written to use the
// AMD or UMD specs. `boot.js` will do a bunch of configuration and attach it''s initializers to `window.onload()`. Because
// we are using RequireJS `window.onload()` has already been triggered so we have to manually call it again. This will
// initialize the HTML Reporter and execute the environment.
require([''boot''], function () {
// Load the specs
require(specs, function () {
// Initialize the HTML Reporter and execute the environment (setup by `boot.js`)
window.onload();
});
});
/******
* Use this require if you''re on Jasmine 1.3
******/
//require([''jquery'', ''jasmine-html''], function ($, jasmine) {
// var jasmineEnv = jasmine.getEnv();
// jasmineEnv.updateInterval = 1000;
// var htmlReporter = new jasmine.HtmlReporter();
// jasmineEnv.addReporter(htmlReporter);
// jasmineEnv.specFilter = function(spec) {
// return htmlReporter.specFilter(spec);
// };
// $(function() {
// require(specs, function(spec) {
// jasmineEnv.execute();
// });
// });
//});
// end 1.3
})();
foo.js:
define([''knockout''], function (ko) {
var message = ko.observable("Go away, World!");
return {
message: message()
};
});
hola.js:
define([''foo''], function (foo) {
return {
message : foo.message
};
});
hello-spec.js:
define([''squire''], function (Squire) {
var injector = new Squire();
var builder = injector
.mock(''foo'', {
message: "Hello, World!"
});
describe(''hello'', function () {
var hello;
beforeEach(function (done) {
// For async:
// accept a "done" parameter and Jasmine will wait...
builder.require([''hello''], function (hi) {
hello = hi;
done(); // ...until you invoke it.
});
/*******
* Use the following if you''re on 1.3
*********/
//var done;
//runs(function () {
// builder.require([''hello''], function (hi) {
// hello = hi;
// done = true;
// });
//});
//waitsFor(function () {
// return done;
//}, "Unable to load dependency not loaded", 750);
// end 1.3
});
it(''is welcoming'', function() {
expect(hello.message).toBe("Hello, World!");
});
});
describe(''hello no mock foo'', function () {
var hello;
beforeEach(function (done) {
// For async:
// accept a "done" parameter and Jasmine will wait...
require([''hello''], function (hi) {
hello = hi;
done(); // ...until you invoke it.
});
/*******
* Use the following if you''re on 1.3
*********/
//var done;
//runs(function () {
// require([''hello''], function (hi) {
// hello = hi;
// done = true;
// });
//});
//waitsFor(function () {
// return done;
//}, "Unable to load dependency not loaded", 750);
// end 1.3
});
it(''is less than welcoming'', function () {
expect(hello.message).toBe("Go away, World!");
});
});
});
Detalles
Líneas
var injector = new Squire();
var builder = injector
.mock(''foo'', {
message: "Hello, World!"
});
burlarse de la dependencia de hola en foo y luego
builder.require([''hello''], function (hi) {
hello = hi;
done(); // ...until you invoke it.
});
carga el módulo de saludo usando el foo burlado. En comparación con el uso, se requiere cargar el hola en la segunda prueba:
require([''hello''], function (hi) {
hello = hi;
done(); // ...until you invoke it.
});
Los documentos de Jasmine http://jasmine.github.io/ pueden informarle sobre la funcionalidad "done ()" (2.0) o "run / waitsFor" (1.3).
Quiero escribir pruebas de JS. El código de producción está escrito con RequireJS. Encontré una biblioteca de prueba llamada Squire.js: https://github.com/iammerrick/Squire.js/
Desde el sitio web Squire.js
Ejecutar genera una función que recibirá una devolución de llamada y la ejecutará después de que se complete la función de prueba. Particularmente útil para los marcos donde la asincronía se maneja con una devolución de llamada. Aquí hay un ejemplo con Mocha.js. Jasmine puede ofrecer este enfoque de devolución de llamada utilizando Jasmin.Async ".
No sé cómo usar esto con Jasmine async. Un pequeño ejemplo sería muy útil.