web-dev-qa-db-fra.com

objet de fenêtre maquette jasmin

Comment se moquer d'un objet fenêtre? Je fais l'extension Firefox et je veux utiliser le jasmin pour les tests javascript.

Dans mon javascript j'ai


function submit() {
...
var url = window.arguments[0];
...
}

Évidemment, je dois me moquer de window.arguments [0] dans le jasmin parce que cet objet n'existe pas s'il ne transmet aucun paramètre de window.openDialog

Ceci est ma tentative de se moquer de "avec"


it("should submit to server", function() {

        var localContext = {
            "window": {
                arguments: ["http://localhost"]
            }

        }

        with(localContext);

Mais j'obtiens toujours cette erreur TypeError: Impossible de lire la propriété '0' de non défini, c'est comme lorsque le test est exécuté window.arguments [0] est effacé avec la vraie fenêtre, parce que si je le fais

window.arguments[0]

à l'intérieur du test, il affiche correctement "http: // localhost". mais quand il s'agit de la méthode submit (), cela montre l'erreur que window.argument n'est pas défini.

42
toy

Le problème est que vous écrasez simplement une propriété de l'objet fenêtre. Et si vous pouvez le faire, le navigateur peut le faire également. Donc, se moquer d'une fonction ou d'une propriété d'un objet global auquel tout le monde peut accéder n'est pas une bonne idée en général, car vous ne pouvez jamais être sûr que vos modifications seront là lorsque vous essayez d'y accéder.

Ce qui m'amène à injection de dépendance . C'est un modèle courant pour rendre votre unité de code testable, en mettant l'accent sur l'unité . Qu'est-ce que cela signifie? Chaque fois que vous créez un nouvel objet ou accédez à un objet global, vous testez non seulement la fonctionnalité unit, mais également la fonctionnalité de votre objet nouvellement créé ou global. Pour ajouter cela, vous ne créez pas les nouveaux objets dans votre unité, mais vous les passez dans. Normalement, vous le feriez dans le constructeur, mais comme dans la fonction JavaScript il y a des objets avec le corps de la fonction comme constructeur, vous pouvez également passer les dépendances simplement dans votre fonction.

Donc, dans votre cas, la fonction dépend de l'objet fenêtre global. Ainsi, au lieu d'essayer d'accéder à l'objet de fenêtre globale, passez-le en tant que paramètre dans votre fonction. En procédant de cette façon, vous pouvez passer l'objet window dans votre code de production et un simple objet JavaScript avec des arguments attribués dans votre test:

function youWannaTest(w){
    console.log(w.arguments[0]);
}

Dans votre poste, appelez la fonction comme ceci:

youWannaTest(window);

Dans votre test, appelez la fonction comme ceci:

youWannaTest({arguments: ['someValue']});
61
Andreas Köberle

Je pense également que l'injection de dépendance est la solution la plus propre.

Votre JS:

function submit(_window) {
    _window = _window || window
    ...
    var url = _window.arguments[0];
    ...
}

Vos tests unitaires:

it('works like a dream', function () {
    var _window = { arguments: ['url'] }
    expect(submit(_window)).toBeTotallyAwesome()
})
3
A.Williams

Oui, vous pouvez vous moquer de l'objet fenêtre.

La première chose que vous devrez faire est d'apporter une modification dans votre code JS: Remplacez window par $ window.

Ensuite, vous pouvez vous moquer de la fenêtre en utilisant le code ci-dessous:

var window = {
  arguments : ['url']
};

maintenant dans votre fichier spec: dans le bloc beforeEach

$controller('controllerName', {$window : window});
0
Ankit Shah