2017-09-10 7 views
3

Dans mon application express, je déclare des gestionnaires de requêtes comme celle-ci (simplifié ici):erreur de demande Simuler avec fonction async

export const CreateProduct = async (req, res, next) => { 
    try { 
    // ProductModel is a sequelize defined model 
    const product = await ProductModel.create(req.body) 
    res.send(product) 
    } catch (err) { 
    // I have raygun setup as the error handler for express 
    // in this example, it will finally return 500 
    next(err) 
    } 
} 

Et utiliser ensuite comme si:

import { CreateProduct } from './create_product' 

export const ProductRouter = express.Router() 
ProductRouter.post('/', CreateProduct) 

Cependant, lors de l'exécution mon test, nyc/istanbul va se plaindre que la ligne 9 est un Uncovered Line (dans mon exemple, c'est la fonction next(err)), comment puis-je simuler l'erreur dans mon exemple?

Répondre

2

Le plus facile à faire est de créer un mécanisme de validation pour votre ProductModel, et lorsque vous créez le produit avec des données non valides, jetez quelques erreurs de validation.

Et dans votre moka vous allez envoyer un corps de produit invalide et il va attraper votre next.

+0

J'accepte votre réponse car c'est la solution la plus courte et la plus simple qui a résolu mon cas particulier. Merci tas! – borislemke

2

Deux des moyens les plus simples possibles de le faire sont les suivantes:

1) Admettre que les contrôleurs ne peuvent pas être testé unitairement, et parce qu'ils ne peuvent pas être testé unitairement, ils seront une partie de vos tests d'intégration et parce que c'est vrai, vous allez en extraire autant de code testable que possible physiquement, et les limiter à faire un peu plus que de composer des morceaux de code qui peuvent être testés. Ce serait bien; un contrôleur Express est en quelque sorte comme une méthode main dans votre application, à partir de la vue d'une demande individuelle, de toute façon, alors le faire mélanger les concepts durs pour décider ce qui est construit est correct, tant que le main ne fait pas le soulever des objets lourds, mais instancier et exécuter des choses qui sont en train de soulever. 2) Composez vos fonctions de façon à ce qu'elles reçoivent tous les accessoires dont elles ont besoin, pour faire leur travail, et encore plus, elles les reçoivent presque toujours d'autres fichiers (pas le fichier dans lequel elles sont définies), à moins que l'affectation est juste une valeur par défaut. Dans le cas d'un contrôleur, si vous souhaitiez que le contrôleur soit testable à l'unité, vous le préconfigureriez pour accepter un ProductModel à utiliser (ou une fonction à utiliser) plutôt que de supposer que vous allez tirer sur le réel. modèle.

export const CreateProduct = (ProductModel) => async (req, res, next) => { 
    const productData = req.body 
    try { 
    const product = await ProductModel.create(productData) 
    res.send(product) 
    } catch (err) { 
    next(err) 
    } 
} 



import { CreateProduct } from './create_product' 
import { ConfigureProductModel } from './somewhere_else' 

export const ProductRouter = express.Router() 
ProductRouter.post('/', CreateProduct(ConfigureProductModel(database))) 

Maintenant, pour tester, vous pouvez facilement créer un CreateProduct où vous passez dans un ProductModel faux. Et si vous utilisez l'exemple, il ConfigureProductModel en tant qu'usine, vous pouvez tester en lui passant une instance db faux (si vous avez, en effet, avoir ce niveau de contrôle). Et personnellement, comme je l'ai dit, en tant que contrôleur, je veux supprimer autant de contrôle que possible, donc je supprimerais probablement la plupart du code impératif.

const CreateProduct = ProductModel => (req, res, next) => 
    ProductModel.create(req.body) 
    .then(product => res.send(product)) 
    .catch(next); 
+0

Merci beaucoup pour votre explication. J'ai choisi d'accepter la réponse d'Alexandru car elle répond directement à mon cas particulier. Cependant, je suis heureux que vous ayez pris le temps d'écrire cette explication géniale. Cela m'a beaucoup aidé à repenser la façon dont je structure mon application Express. – borislemke

+0

@borislemke Juste, et je ne m'inquiète pas pour ça, pour moi. Gardez à l'esprit que vous avez actuellement besoin d'Internet en direct et de connexions DB en direct, afin d'exécuter des tests.Beaucoup de gens dans de nombreux systèmes ont eu leurs cartes de crédit chargées, dans de tels systèmes, et beaucoup d'autres ne pouvaient pas faire de travail alors qu'ils n'étaient pas connectés à un réseau. Ces suggestions ne sont pas seulement pour une meilleure couverture, des tests plus faciles ou un code plus propre; ce ne sont que quelques-uns des effets secondaires. – Norguard