2017-02-20 50 views
1

我在Redux应用程序中模仿第三方节点模块的功能时遇到了问题。Redux中间件中的模拟节点模块(Jest)

我想测试拦截某个动作并从第三方npm包中调用函数的中间件函数。 (该模块是AWS-IOT装置-SDK,函数建立WebSocket连接到AWS的IoT服务)

import awsIot from 'aws-iot-device-sdk' 

// ... 

const customMW = (store => { 

    let websocket = null 

    return next => action => { 
    switch(action.type) { 

     case 'CONNECT': 

     websocket = awsIot.device({ 
     accessKeyId: action.accessKey 
     // other params... 
     }) 

     // Listen to events etc. 
     break 
     // ... 
    } 
    } 
}) 

awsIot.device()建立WebSocket连接,并能正常工作。

然而,当我尝试测试customMW功能,awsIot.device()被称为即使我尝试嘲笑它(存储和明年适当嘲笑):

test.js 

describe('middleware test',() => { 

    it('does something',() => { 

    awsIot.device = jest.fn() 
    action = { type: 'CONNECT' } 
    customMW(store)(next)(action) 
    // assertions... 
    }) 
}) 

当我运行测试,我得到的错误'accessKey'未定义。所以中间件运行原来的awsIot.device()函数,它正在寻找'accessKey'作为动作的一部分被传入。

我在其他地方使用过这种模式,并取得了成功。有谁知道为什么这个功能没有被嘲笑?

回答

2

若要模拟您要导入到要测试的文件中的内容,必须使用jest.mock。这将在实际导入之前覆盖导入的模块。如果你想检查awsIot.device被称为在你测试你必须输入你考的好,然后用期待这样的模块:

import awsIot from 'aws-iot-device-sdk'//only needed if you wanna test that device method was called 

jest.mock('aws-iot-device-sdk',()=>({ 
    device: jest.fn() 
})) 

describe('middleware test',() => { 

    it('does something',() => { 
    action = { type: 'CONNECT' } 
    customMW(store)(next)(action) 
    expect(awsIot.device).toHaveBeenCalled() 
    }) 
}) 
+0

我仍然得到相同的错误。好像开玩笑似乎完全无视我嘲笑的功能。 –

+0

你可以在你的组件中记录'awsIot',检查它是否被嘲弄。 –

+0

是的,它很奇怪。事实上,如果我扩展你的建议并添加一个模拟实现到'.device',我可以看到在我的原始文件中正确返回。但由于某种原因,下一行(调用完全相同的函数似乎忽略了这一点...) –

0

我设法由Andreas的建议,用相结合来解决这个问题事实上,我必须在测试中提供正确的“形状”动作。

action = { 
    type: 'CONNECT', 
    accessKeyId: 'testKey' 
} 

看来嘲笑功能仍会读传递给它的参数,如果有引用错误有那么就会报错。