2014-11-28 9 views
8

Ich habe eine sehr einfache mixin reagieren, die jQuery verwendet ein Ereignis auslösenReagieren Komponente jQuery verwenden, ohne erfordern - Scherz Einheit testet

MyMixin = { 
    trackStructEvent: function() { 
    args = Array.prototype.slice.call(arguments); 
    $('body').trigger('myEvent', args); 
    } 
module.exports = MyMixin 

Diese in die Haupt-Website als Teil einer neuen Reihe von Komponenten importiert wird unter Verwendung von browserifizieren. Da die Haupt-Site, die diese Komponenten enthält, immer jQuery enthält, möchte ich jQuery nicht mit browserify benötigen, da es dupliziert wird.

Dies ist kein Problem in Bezug auf das Verhalten - aber es verursacht Probleme beim Ausführen von Jest zum Komponententest die Komponenten mit diesem Mixin werfen den Fehler.

Ich weiß, dass ich das beheben kann, indem ich jQuery durch browserify, aber das wird 2 Kopien in meine Website laden.

Gibt es irgendeine Möglichkeit im Scherz, meiner reagierenden Komponente zu sagen, dass jQuery bereits im Fenster existiert und sich nicht darum kümmern muss?

+0

Haben Sie versucht, 'var $ = window.jQuery'? – David

+1

Eine andere Möglichkeit ist die Verwendung der 'externen' Option in browserify – David

+0

@David - die Verwendung von' external' schien in meiner Komponente zu funktionieren, aber ich konnte es nicht mit dem Scherz spielen. Für jetzt habe ich hinzugefügt, dass "$" vor dem Aufruf definiert ist. Ich werde es nicht als Antwort geben, da es keine wirkliche Lösung für das Problem ist. Es lässt mich einfach meine Scherze passieren –

Antwort

7

Ich habe ein ähnliches Problem, aber ich denke, wo ich bis jetzt dein Problem lösen muss. Sie müssen erfordern die Verwendung in Ihrer Dateien reagieren unter

$ jQuery definieren
var $ = require('jquery'); 

MyMixin = { 
    trackStructEvent: function() { 
     args = Array.prototype.slice.call(arguments); 
     $('body').trigger('myEvent', args); 
    } 
module.exports = MyMixin 

Sie müssen dann Scherz sagen, nicht jquery

jest.dontMock('jquery') 

Dann wird Ihr Scherz Unit-Tests passieren sollte verspotten (vorausgesetzt, sie aren Ich überprüfe nicht, was jQuery macht - hier fallen meine Tests um.

Sie müssen browserify auch mitteilen, dass jQuery extern ist, dann werden alle Ihre Verweise auf $ definiert, die jquery-Bibliothek wird zum Testen geladen, ist aber nicht in Ihrem browserify-Bundle enthalten. (Verwendung browserify-shim)

+1

Wir haben jQuery von unserer Seite entfernt, jetzt haben wir eine vollständige Reaktion eingerichtet, also keine Notwendigkeit für DOM-Manipulation. Das sieht so aus, als würde es die Probleme lösen, die wir hatten, und da es Ihr Problem gelöst hat, ist es sinnvoll, die akzeptierte Antwort zu sein. Vielen Dank! –

2

Was mit Ich werde ist:

if (process.env.NODE_ENV === 'test') window.$ = require('jquery');

Ich hoffe, das jemand hilft!

UPDATE:

ich import $ from 'jquery' in alle begonnen haben Reagieren Dateien, die jQuery verwenden. Das entfernt die Abhängigkeit von window. $ Ist der Typ von jQuery, den ich erwarte (Ich habe Probleme mit anderen Bibliotheken bekommen, die mit window. $ Zusammenhängen. Zuerst war ich besorgt über den Import von jQuery überall, weil ich befürchtete, dass dies meine erhöhen würde Bundle Größe Aber die Art und Weise der Bündelung, all diese Importe werden auf ein Singleton zeigen, so Bundle-Größe würde nicht zunehmen.

2

Ich für meinen Teil bin nicht interessiert, die jQuery-Funktionalität in meinen Komponenten zu testen meine Anwendung auf nicht jQuery in mein Bündel enthalten, da es verwendet wird, und enthalten alle über die Website So habe ich zum Beispiel folgendes getan:..

// SubmitRender.js 

// ...import statements... 

var SubmitRender = React.createClass({ 
    componentWillMount: function() { 
    $('form').on('submit', (e)=>{ 
     this.handleSubmit(e); 
    }); 
    }, 

    // ...more code... 
}); 
export default SubmitRender; 

// SubmitRender.spec.js 

// ...import statements... 

describe('SubmitRender',() => { 
    beforeAll(() => { 
    // mocking jQuery $() 
    global.window.$ = jest.fn(() => {return {on: jest.fn()}}); 
    }); 

    it('renders without error',() => { 
    expect(() => render(<SubmitRender />)).not.toThrow(); 
    }); 
}); 

Ich weiß, dass meine Komponente nicht ohne Aufruf der $-Funktion mounten wird. Also habe ich diese Funktion nur mit jest.fn in einer beforeAll() gespielt.Jetzt weiß ich auch, dass meine jQuery-Funktion in meiner eigentlichen Komponente verkettet ist. Ich weiß also, dass ich auch die .on() von jQuery berücksichtigen muss, also stelle ich sicher, dass ein Objekt mit einer on-Funktion zurückgegeben wird. Es gibt keine weitere Verkettung, also kann ich damit aufhören.

Wenn ich eine komplexere Reihe von verketteten Funktionen hatte, konnte ich so etwas tun:

beforeAll(() => { 
    // mocking jQuery $() 
    var fakeQuery = jest.fn(() => { 
    return { 
     on: fakeQuery, 
     off: fakeQuery, 
     click: fakeQuery 
    } 
    }) 
    global.window.$ = fakeQuery; 
});