2017-06-05 2 views
0

Ich habe ein Problem mit Stubbing/Test-Funktion, die Fetch verwendet.Wie stub fetch api Anfrage

Mit einfachen Beispiel:

export const clickTimeseries => { 
    return fetch('...url...') 
    .then(response => { 
     if(response.status == 200) 
     return response.json() 
     else 
     throw 'something' 
    }) 
    .then(json => { 
     return { 
     success: true, 
     data: json, 
     } 
    }) 
    .catch(err => { 
     return { 
     success: false, 
     error: err, 
     } 
    }) 
} 

Und mein Test:

import { expect } from 'chai' 
import sinon from 'sinon' 

import Promise from 'es6-promise' 
Promise.polyfill() 

import 'whatwg-fetch' 

import clickTimeseries from './above' 

const jsonOK = body => { 
    const mockResponse = new Response(JSON.stringify(body), { 
    status: 200, 
    headers: { 
     'Content-type': 'application/json' 
    } 
    }) 

    return Promise.resolve(mockResponse) 
} 

describe('APIs',() => { 
    describe('Click timeseries',() => { 
    it('builds a correct data on success',() => { 
     sinon.stub(window, 'fetch').returns(jsonOK({stuff: [1,2,3]})) 

     expect(clickTimeseries()).to.eq({ 
     success: true, 
     data: {stuff: [1,2,3]} 
     }) 
    }) 
    }) 
}) 

Ich erhalte Fehler:

expected { Object (, _state, ...) } to equal { success: true, data: {stuff: [ 1, 2, 3, 4 ] }} 

Es sieht aus wie spendTimeseries Renditen versprechen, statt des Ergebnisses ruft beide then Blöcke.

Wie müssten Sie Ihren Test einrichten, damit er bestanden wird?

Antwort

3

Es hat einige Zeit gedauert mit dem Code zu spielen, bis ich merkte, was falsch war, weil alles korrekt aussah. Und tatsächlich war es das. Abgesehen von einer Sache: Das Ergebnis, für das Sie testen, wird asynchron geliefert, aber Sie testen es synchron. Das bedeutet, dass Sie Ihren Test asynchron ändern müssen.

Ich gehe davon aus, dass Sie Mocha als Test-Runner verwenden, und es gibt zwei Möglichkeiten, Async-Code zu testen. Eine Standardmethode für jeden Async-Code und eine spezielle Art, mit Promises umzugehen. Sie können alles verwenden, was zu Ihrem Stil passt.

Wenn Sie Asynchron-Code haben, wo das Ergebnis zu einem späteren Zeitpunkt geliefert wird, ist dies die allgemeine Formel:

it('should test an async function', (callback) => { 
    const expectedResult = 42; 
    doSomethingAsync((result) => { 
     try{ 
      expect(expectedResult).to.equal(result); 
      callback(); 
     } catch(err) { 
      callback(err); 
     } 
    }) 
}); 

Für ein Versprechen der Rückkehr Funktion dies würde wie folgt aussehen:

it('should test a promise', (callback) => { 
    const expectedResult = 42; 
    doSomethingAsync().then((result) => { 
     expect(expectedResult).to.equal(result); 
     callback(); 
    }).catch(callback); 
}); 

Mokka hat etwas Zucker für Versprechungen es ermöglicht, die letzte Funktion wie diese zu schreiben (kein Rückruf in Funktion Wrapper!):

it('should test a promise',() => { 
    const expectedResult = 42; 
    return doSomethingAsync().then((result) => { 
     expect(expectedResult).to.equal(result); 
    }) 
}); 

Fazit: nur den Test ändern wie folgt zu lesen:

return clickTimeseries().then(result => { 
    expect(result).to.eq({ 
     success: true, 
     data: {stuff: [1,2,3]} 
    }) 
}) 
+0

Dank für Ihre Zeit! Finde Kumpel. – Kocur4d