2017-01-13 35 views
9

aşağıdaki Redux eylem yaratıcısı vardır:nasıl ünite thunk eylem ile deney mapDispatchToProps için

export const keyDown = key => (dispatch, getState) => { 
    const { modifier } = getState().data; 
    dispatch({ type: KEYDOWN, key }); 
    return handle(modifier, key); // Returns true or false 
}; 

Ve aşağıdaki bağlı bileşen: Ben dispatch sağlamak için bir test yazmaya çalışıyorum

export const mapDispatchToProps = dispatch => ({ 
    onKeyDown: e => { 
     if(e.target.tagName === "INPUT") return; 
     const handledKey = dispatch(keyDown(e.keyCode)); 
     if(handledKey) { 
      e.preventDefault(); 
     } 
    } 
}); 

tagName, "INPUT" dışında bir şey olduğunda keyDown eylemiyle çağrılır. Tahminen bu ok işlevlerini kullanarak bir ilgisi olduğunu

import { spy } from "sinon"; 
import keycode from "keycodes"; 
import { mapDispatchToProps } from "./connected-component"; 
import { keyDown } from "./actions"; 

// Creates a simple Event stub... 
const createEvent = (tag, keyCode) => ({ 
    target: { 
     tagName: tag.toUpperCase() 
    }, 
    preventDefault: spy(), 
    keyCode 
}); 

it("Dispatches a keyDown event with the specified keyCode if the selected element is not an <input>",() => { 
    const dispatch = spy(); 
    const keyCode = keycode("u"); 
    mapDispatchToProps(dispatch).onKeyDown(createEvent("div", keyCode)); 
    // This fails... 
    expect(dispatch).to.have.been.calledWith(keyDown(keycode)); 
}); 

: Bu benim sınavım? Sevkıyatın beklediğim fonksiyon imzası ile çağrıldığından emin olmanın herhangi bir yolu var mı?

+0

Yani o dize eşitliği ve Dönüş ifadesi çalışmalarını test ya da bir geliştirici yanlışlıkla kaldırmak olmadığını edilir? Tanrım, çoğu birim testinden hoşlanmıyorum :( –

+0

Öncelikle 'gönderme 'aslında çağrılır. Çoğu zaman eylem yaratıcısını gönderime geçmeden çağırırım.Konuşma eyleminin de önemli olduğunu, yani beklemenin (gönderim) olduğunu kontrol ediyorum. to.have.been.called' yeterli olmaz düşünmüyorum – CodingIntrigue

cevap

3

En basit çözüm, başka bir yanıtta (+1) önerildiği gibi keyDown() no'lu notta yer almak olabilir. İşte keyDown() yana


actions ithal tüm üsleri ele almaya çalışan bir farklı bir yaklaşım ..., var yapabiliriz stub o keyCode ile çağrılan her bir dummy döndürülecek değer fonksiyonu:

import * as actions; 
keyDown = stub(actions, "keyDown"); 
keyDown.withArgs(keyCode).returns(dummy); 

Ardından, unit tests, dispatch numaralı telefonu doğru bir şekilde düzenlediğimiz dummy numaralı telefonla teyit eder. dummy'un sadece keyDown() numaralı kılavuzumuz tarafından iade edilebileceğini biliyoruz, bu nedenle bu kontrol ayrıca keyDown()'un çağrıldığını doğrular.

mapDispatchToProps(dispatch).onKeyDown(createEvent("div", keyCode)); 
expect(dispatch).to.have.been.calledWith(dummy); 
expect(keyDown).to.have.been.calledWithExactly(keyCode); 

biz anahtar etkinliği hedef bir <input> olduğunda gönderilir değil olduğunu doğrulamak için birim testleri eklemek gerekir, titiz olmak.

mapDispatchToProps(dispatch).onKeyDown(createEvent("input", keyCode)); 
expect(dispatch).to.not.have.been.called; 
expect(keyDown).to.not.have.been.called; 

Biz verilen dispatch geri arama doğru anahtar olay ve anahtar koduyla çağrılan olduğunu doğrulayarak da testkeyDown() kendisi tek başına yapmalıdır:

expect(dispatch).to.have.been.calledWith({type: actions.KEYDOWN, key: keyCode}); 

Bağlantılar

+0

Cevabınız için çok teşekkürler. ES6 ithalatının bu şekilde konduğunu farketmedim ama mantıklı geliyor. Aynı noktada, cevabın çabası için verilen ödülün ödülünü verdim. – CodingIntrigue

+0

@CodingIntrigue Sorun değil :) – tony19

2

keyDown(keycode) her seferinde yeni bir işlev oluşturur ve her işlev örneği farklıdır, test durumu beklendiği gibi başarısız olur.

Bu

keyDown yarattığı hepsini hatırlayabilirsiniz fonksiyonları düzeltilebilir: Aynı keycode geri dönüşü

ezberlenmesi ile
let cacheKeyDown = {}; 
export const keyDown = key => cacheKeyDown[key] || cacheKeyDown[key] = (dispatch, getState) => { 
    const { modifier } = getState().data; 
    dispatch({ type: KEYDOWN, key }); 
    return handle(modifier, key); 
}; 

, keyDown aramaları aynı işlevi. @DarkKnight olarak

1

keyDown her çağrı için yeni bir işlev döndürüyor, (+1 var) sözü, bu nedenle test keyDown(keyCode) çünkü! = keyDown(keyCode) başarısız olur. Eğer keyDown sizin gerçek uygulama değiştirmek istemiyorsanız

, sadece testlerde alay edebilirsiniz:

İlgili konular