2017-01-12 6 views
0

Ich versuche Nock verwenden, um einige HTTP-Verkehr in meiner Anwendung zu Testzwecken abzufangen/zu verspotten. Unsere App authentifiziert sich auf einer unserer Websites und ich brauche Nock, um HTTP 200 (mit JSON-Daten) und HTTP 401 (ohne Daten) zu imitieren, um Verhaltensweisen zu testen, wenn der Benutzer dort angemeldet ist bzw. nicht eingeloggt ist. .Wie kann ich Nock und Mocha gut zusammen spielen lassen?

Ich habe zwei Tests, die beide korrekt funktionieren, wenn sie alleine ausgeführt werden, aber wenn ich die gesamte Testsuite ausführen, schlägt eine von ihnen immer fehl. Ich erkenne, dass Nock ist gemeinsamen Status, weil es ändert, wie node.js selbst behandelt Netzwerkverkehr und ich nehme an, dass das ist die Ursache der Race-Bedingung, aber ich kann nicht die einzige Person sein, die jemals zwei verschiedene Nock Interzeptoren für die gleiche Anfrage verwendet zwei verschiedene Tests, also weiß ich, dass mir etwas fehlt.

Kann mir jemand helfen herauszufinden, warum diese Tests aufeinander treten?

Meine Frage bezieht sich auf How to retest same URL using Mocha and Nock?, aber ich habe die Dinge dort vorgeschlagen und sie haben nicht geholfen.

Meine Testdateien (die wiederum beide gut funktionieren, wenn einzeln aufgerufen, aber nicht, wenn sie als Teil des gleichen Testdurchlauf ausgeführt wird) wie folgt aussehen:

import { expect } from 'chai'; 
import nock from 'nock'; 

import * as actionTypes from '../../src/constants/action-types'; 
import * as panoptes from '../../src/services/panoptes'; 

import { user } from '../modules/users/test-data'; 

const stagingHost = 'https://my-staging-server.org'; 

describe('Panoptes',() => { 
    afterEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    beforeEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    describe('with a valid user', function (done) { 
    let lastAction = null; 

    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'location': 'https://localhost:3000', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(200, { 
     users: [user], 
     }); 

    panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => { 
     nock.removeInterceptor(scope); 
     done(); 
    }); 

    it('should know when somebody is logged in', function() { 
     expect(lastAction).to.not.be.null; 
     expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(lastAction.user).to.not.be.null; 
     expect(lastAction.user.id).to.equal(user.id); 
     expect(lastAction.user.login).to.equal(user.login); 
    }); 
    }); 
}); 

und

import { expect } from 'chai'; 
import nock from 'nock'; 

import * as actionTypes from '../../src/constants/action-types'; 
import * as panoptes from '../../src/services/panoptes'; 

const stagingHost = 'https://my-staging-server.org'; 

describe('Panoptes',() => { 
    afterEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    beforeEach(function (done) { 
    nock.cleanAll(); 
    nock.disableNetConnect(); 
    done(); 
    }); 

    describe('with no user', function (done) { 
    let lastAction = null; 

    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'Cache-Control': 'no-cache', 
     'location': 'https://my-staging-server.org/users/sign_in', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(401); 

    panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => { 
     nock.removeInterceptor(scope); 
     done(); 
    }); 

    it('should know that nobody is logged in', function() { 
     expect(lastAction).to.not.be.null; 
     expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(lastAction.user).to.be.null; 
    }); 
    }); 
}); 
+0

Welchen Fehler sehen Sie, wenn Sie beide Tests zusammen ausführen? –

+0

Ich bekomme keinen Fehler, es ist nur, dass der zweite Test fehlschlägt, wenn es passieren sollte. Es scheint, dass der zweite Test durch den Schein des ersten Tests beeinflusst wird. –

Antwort

0

Ich denke, das Problem ist nicht in Nock, aber mit der Reihenfolge der Reihenfolge Ihrer Mocha Hooks Reihenfolge:

Nehmen Sie dieses Beispiel:

describe('Panoptes',() => { 

    afterEach(function() { 
    console.log('ORDER: after each'); 
    }); 

    beforeEach(function() { 
    console.log('ORDER: before each'); 
    }); 

    describe('with a valid user', function() { 

    console.log('ORDER: with a valid user'); 

    it('should know when somebody is logged in', function() { 
     console.log('ORDER: should know when somebody is logged in'); 
    }); 

    }); 

    describe('with no user', function() { 

    console.log('ORDER: with no user'); 

    it('should know that nobody is logged in', function() { 
     console.log('ORDER: should know that nobody is logged in'); 
    }); 

    }); 

}); 

Wenn wir es laufen bekommen wir die folgende Reihenfolge bei der Ausgabe:

ORDER: with a valid user 
ORDER: with no user 
ORDER: before each 
ORDER: should know when somebody is logged in 
ORDER: after each 
ORDER: before each 
ORDER: should know that nobody is logged in 
ORDER: after each 

afterEach/beforeEach läuft vor und nach jedem it jedoch die describe Körper ausgewertet wird, bevor diese Haken genannt werden. Sie sollten jeden Ihrer Nocks in eine before wickeln. (Auch describe kein done Argument)

So etwas wie dies funktionieren sollte:

describe('with no user', function() { 

    before(function() { 
    const scope = nock(stagingHost) 
     .get(/^\/oauth\/authorize/) 
     .reply(302, '', { 
     'Cache-Control': 'no-cache', 
     'location': 'https://my-staging-server.org/users/sign_in', 
     'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', 
     'X-Frame-Options': 'SAMEORIGIN', 
     'X-XSS-Protection': '1; mode=block', 
     }); 

    scope 
     .get(/^\/api\/me/) 
     .reply(401); 
    }); 


    it('should know that nobody is logged in', function (done) { 
    panoptes.checkLoginUser((action) => { 
     expect(action).to.not.be.null; 
     expect(action.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(action.user).to.be.null; 
     done(); 
    }); 
    }); 

}); 
+0

Vielen Dank für Ihren Vorschlag! Ich werde es ausprobieren und kommentieren, sobald ich sehe, ob das das Problem löst. –

+0

Dies tat genau das, was ich brauchte. Leider versagt mein Test immer noch, aber jetzt liegt der Fehler in unserem Code, und weil ich es vorher falsch getestet hatte, hatte ich es nicht gesehen! –

+0

Froh, es hat funktioniert! Viel Glück! –

0

Ich benutzte Antwort sanketh-katta ist, die ich Kredit für die Lösung gebe, aber leicht modifiziert, die it Block ich bin auch so meinen Code auf Vollständigkeit:

it('should know when somebody is logged in', function(done) { 
    panoptes.checkLoginUser((action) => { 
    try { 
     expect(action).to.not.be.null; 
     expect(action.type).to.equal(actionTypes.SET_LOGIN_USER); 
     expect(action.user).to.not.be.null; 
     expect(action.user.id).to.equal(user.id); 
     expect(action.user.login).to.equal(user.login); 
     done(); 
    } catch (ex) { 
     done(ex); 
    } 
    }); 
}); 

Früher, als einer der Tests fehlschlagen würde, der done() Anruf würde nie erreicht werden, und so würde ich die Meldung, dass der Test abgelaufen war ins Tead eines bestimmten Fehlers.

+0

Vielleicht möchten Sie [Chai-as-Versprochen] (https: // github.com/domenic/chai-as-promised), das genau dieses Problem löst. –

Verwandte Themen