Jest: Testez si objet, tableau ou chaîne.

Créé le 3 mai 2017  ·  29Commentaires  ·  Source: facebook/jest

Existe-t-il un moyen de vérifier si un composant est un objet, un tableau ou une chaîne ? Cela serait similaire au "should.be.a" de chai Ex. : validationResult.SSN[0].should.be.a('string').

Commentaire le plus utile

Une simple extension toBeType pour ceux qui le souhaitent

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Assez simple à mettre en œuvre. Vraiment devrait être dans le noyau tbh.

Remarque - si vous mettez cette extension dans vos fichiers de configuration, vous la voulez dans setupTestFrameworkScriptFile PAS setupFiles (car l'extension n'est disponible que dans le premier)

Tous les 29 commentaires

Non, il n'y en a pas. Vous trouverez la liste de tous les matchers disponibles ici : https://facebook.github.io/jest/docs/en/expect.html

Vous pouvez également utiliser du JavaScript simple ou une bibliothèque d'aide comme lodash pour cela :

test('name', () => {
  // array
  expect(Array.isArray(['value'])).toBe(true);
  // string
  expect(typeof 'value').toBe('string');
  // object
  expect({value: 'value'}).toBeTruthy();
  expect(typeof {value: 'value'}).toBe('object');
})

Point mineur - cela n'aide pas avec les résultats promis.

expect(somePromise).resolves.toBe(...) à ce stade, il n'y a aucun moyen de vérifier le type. Si vous ne vous souciez pas ce que le contenu est juste que c'est une chaîne. J'espérais que expects.stringContaining("") soit une solution de contournement, mais cela ne fonctionne pas non plus.

@abritinthebay Je suis exactement dans cette situation et c'est le premier résultat dans Google, peut-être devrait-il être rouvert ?

Il faudrait certainement y réfléchir un peu plus. Ma solution de contournement consistait à ajouter à la chaîne afin que la partie typeof . par exemple:

expect(somePromise.then(data => typeof data)).resolves.toBe("object");

ça marche, mais ce n'est pas vraiment propre.

@thymikee La vérification de types de choses est un cas d'utilisation suffisamment courant (universel) pour qu'il n'y ait aucune excuse pour un framework de test qui en manque. Vos alternatives sont inacceptables car nous perdons tout contexte de ce que nous testons.

Ce expect(Array.isArray(['value'])).toBe(false); échoue avec

expect(received).toBe(expected)
    Expected value to be (using ===):
      false
    Received:
      true. 

Donc, soit nous recevons de terribles messages d'assertion, soit nous devons étendre Jest pour prendre en charge ce type de vérification. N'est-il pas plus logique pour les mainteneurs de Jest de le faire une fois par opposition à chaque personne qui utilise nécessite ces fonctionnalités pour les implémenter elles-mêmes ?

Créez vos propres matchers avec expect.extend puis publiez-les en tant que module npm. S'il devient populaire, nous pourrions éventuellement le fusionner avec le noyau Jest ;)

Une simple extension toBeType pour ceux qui le souhaitent

expect.extend({
    toBeType(received, argument) {
        const initialType = typeof received;
        const type = initialType === "object" ? Array.isArray(received) ? "array" : initialType : initialType;
        return type === argument ? {
            message: () => `expected ${received} to be type ${argument}`,
            pass: true
        } : {
            message: () => `expected ${received} to be type ${argument}`,
            pass: false
        };
    }
});

describe("testing extended expect", () => {
    it("tests normal types correctly", () => {
        expect("").toBeType("string");
        expect({}).toBeType("object");
        expect(1).toBeType("number");
    });
    it("tests array types correctly", () => {
        expect([]).toBeType("array");
    });
    it("works with promises", () => {
        expect(Promise.resolve([])).resolves.toBeType("array");
    });
});

Assez simple à mettre en œuvre. Vraiment devrait être dans le noyau tbh.

Remarque - si vous mettez cette extension dans vos fichiers de configuration, vous la voulez dans setupTestFrameworkScriptFile PAS setupFiles (car l'extension n'est disponible que dans le premier)

Merci @abritinthebay

J'ai donc emballé cela dans un module npm si les gens le souhaitent :

https://www.npmjs.com/package/jest-tobetype

describe("assertion framework", ()=> {
 it("should check primitive types", () => {
   expect(expect.toBeA).toBeA("function")
  })
})

Échec : expect(...).toBeA n'est pas une fonctionTypeError : expect(...).toBeA n'est pas une fonction

https://github.com/jest-community/jest-extended a tous les matchers de type que vous pourriez souhaiter (je pense).

J'ai utilisé toBeInstanceOf dans mes tests :

expect($wrapper.vm.countries).toBeInstanceOf(Array);

Créez ensuite vos propres matchers avec expect.extend et publiez-les en tant que module npm. S'il devient populaire, nous pourrions éventuellement le fusionner avec le noyau Jest ;)

Ouais, et peut-être écrire votre propre cadre de plaisanterie, pendant que vous y êtes.

Celui-ci pourrait bien figurer parmi les pires réponses que vous puissiez obtenir sur GitHub.

Donc @abritinthebay a fait exactement ce qui était demandé par @thymikee (ce qui était bien plus que la pull request standard).

Maintenant que cette âme courageuse a fait tout le travail, quand le reste d'entre nous pourra-t-il enfin obtenir ce matcher (sans avoir à installer encore une autre bibliothèque) ? Les mainteneurs poussent-ils toujours l'idée que cela n'appartient pas à Jest, ou cela est-il simplement tombé de leur radar ?

Nous sommes assez stricts avec ce qui en fait le noyau et n'ajoutons généralement pas de mélangeurs de sucre. Jest core est une architecture assez grande et chaque matcher que nous ajoutons augmente le coût de maintenance

Pour le sucre, nous recommandons généralement https://github.com/jest-community/jest-extended

Le sucre d'un homme est une fonction vraiment utile et logique d'un autre homme (ou dans ce cas, d'au moins sept autres personnes) qui appartient à la bibliothèque principale.

Évidemment, en tant que mainteneur, votre vote l'emporte sur tous les nôtres, et vous avez toutes sortes de préoccupations que nous n'avons pas, donc je respecte pleinement cela. Mais je vous demanderais simplement de voir pourquoi tout le monde ici considère que cette fonctionnalité appartient à la bibliothèque principale (si fortement qu'une personne a franchi plusieurs étapes pour écrire le code pour vous). Il y a un besoin ici, et si vous l'ignorez, les utilisateurs de la

.to.be.an.instanceOf ne sera pas le nombre d'utilisateurs qui pensent vérifier les types, donc pour ces utilisateurs, même si vous le voyez comme du sucre, vous leur refusez effectivement la possibilité de vérifier les types dans Jest sans bibliothèque supplémentaire.

Ouais je t'entends. Pour être clair, par "sucre", j'entendais une syntaxe conçue pour rendre les choses plus faciles à lire ou à exprimer . Le sucre, par définition, est une variante d'une caractéristique qui existe déjà

Dans ce cas, nous avons :

// Supported
expect(typeof foo).toBe('string');

// Proposed Sugar
expect(foo).toBeType('string');

Ce n'est donc pas que nous ne prenons pas en charge la vérification des types. Nous faisons. Nous soutenons la première option. Cette option utilise le matcher toBe lequel nous avons passé beaucoup de temps à corriger les bogues et à peaufiner le message, afin que les utilisateurs aient une bonne expérience

Il y a près de 60 matchers dans Jest-extended et beaucoup d'entre eux sont du sucre pur. Pour n'importe lequel de ces matchers, vous pourriez probablement trouver au moins 7 autres personnes qui les trouvent vraiment utiles, donc si c'était l'heuristique que nous avons utilisée pour ajouter au noyau, nous passerions probablement tout notre temps à maintenir les matchers

Pour être tout à fait juste, la plupart des matchers sont du "sucre" à un certain niveau. Je veux dire que toBeGreaterThanOrEqual est juste du sucre pour expect(foo >= bar).toBe(true);

Les matchers sont vraiment _presque tous_ du sucre autour des instructions booléennes ;)

(Je dis cela pour ne pas creuser, juste pour souligner que c'est... une ligne très floue)

Comme l'a suggéré abritinthebay, il ne s'agit pas vraiment de sucre, mais de sucre « nécessaire » et « inutile » (pour la bibliothèque principale). Vous avez un tas de personnes dans ce fil qui disent "hé, être capable de vérifier tous les types est quelque chose qui devrait être au cœur d'une bibliothèque de test" (c'est-à-dire que c'est nécessaire).

Écoutez-nous ou pas, encore une fois en tant que mainteneur, vous avez beaucoup d'autres préoccupations. Mais je ne pense pas que la bonne réponse soit de venir dire « le vôtre est simplement du sucre intrinsèquement inutile » (c'est moi qui essaie de vous paraphraser, pas d'essayer de mettre des mots dans votre bouche) alors que ce n'est pas inhérent : c'est à 100% votre appel si Jest peut vérifier tous les types ou non hors de la boîte.

qu'en est-il, n'est-ce pas difficile :P?

expect(Array.isArray(['your', 'array'])).toBe(true);

expect(typeof something === "object").toBe(true); 
// - or -
expect(something instanceof Object).toBe(true);

expect(typeof something === "string").toBe(true); 

@nahumzs Bien que cela fonctionne, le problème est que sur votre sortie de test en cas d'échec, il dira « faux attendu pour être vrai », ce qui n'est pas très utile ;)

Je pense que c'est la voie à suivre :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

J'ai refactorisé l'implémentation fournie par @abritinthebay. Cela me semble un peu confortable à travailler.

```javascript
attendre.étendre({
/ ** @param { } reçu
* @param {chaîne|chaîne[]} argument
* @return {{pass:boolean,message:(function():string)}}
*/
toBeType(reçu, argument) {
const isCorrectType = arg => {
const receiveType = typeof reçu ;

        const checkForSingle = arg => {
            const type = receivedType === 'object'
                ? Array.isArray(received)
                    ? 'array'
                    : receivedType
                : receivedType;

            return type === arg;
        };

        const checkForArr = arg => {
            const reducer = (prev, curr) => prev || isCorrectType(curr).isCorrect;

            return arg.reduce(reducer, false);
        };

        return {
            receivedType,
            isCorrect: Array.isArray(arg)
                ? checkForArr(arg)
                : checkForSingle(arg)
        };
    };

    const {isCorrect, receivedType} = isCorrectType(arg);

    return {
        pass: isCorrect,
        message: () => {
            const toBe = Array.isArray(arg)
                ? arg.join(`' or '`)
                : arg;

            return `Expected '${received}' of '${receivedType}' type to be of '${toBe}' type(s)`;
        }
    };
}

});

Vous devriez consulter mon module (lien ci-dessus). Ça fait un peu plus que ça. Mais si cela fonctionne pour vous : utilisez-le !

Je pense que c'est la voie à suivre :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})

Cela fonctionne comme un charme ainsi que plus lisible et maintenable pour l'avenir.

Je pense que c'est la voie à suivre :)

describe('type check', () => {
    test('should be type string', () => {
        expect(typeof '').toBe('string')
    })

    test('should be type number', () => {
        expect(typeof 10).toBe('number')
    })

    test('should be type boolean', () => {
        expect(typeof true).toBe('boolean')
    })

    test('should be type undefined', () => {
        expect(typeof undefined).toBe('undefined')
    })

    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
    })

    test('should be type function', () => {
        expect(typeof function() {}).toBe('function')
    })

    test('should be type null', () => {
        expect(typeof null).toBe('object')
    })
})
    test('should be type object', () => {
        expect(typeof { foo: 'bar' }).toBe('object')
        // passes
        expect(typeof ['foo', 'bar']).toBe('object')
        // passes
        expect(typeof null).toBe('object')
    })

??

C'est pourquoi je suggère mon addon ci-dessus : prend soin de cela.

InstanceOf est légèrement meilleur mais sujet à des problèmes similaires.

Lien vers celui-ci :

https://www.npmjs.com/package/jest-tobetype

merci pour la solution @abritinthebay

Une autre solution:

expect('example').toEqual(expect.any(String));
expect(123).toEqual(expect.any(String));

Le second échouerait avec :

    Expected: Any<String>
    Received: 123
Cette page vous a été utile?
0 / 5 - 0 notes