2019年10月27日

UnhandledPromiseRejectionWarningの解消にsinon.spyを使用する

Vue.js入門 基礎から実践アプリケーション開発まで」(第2版)を写経していたのだが、
test実行中にUnhandledPromiseRejectionWarningがどうしても解消できず苦戦した。
解消方法を残しておく。


環境

  • debian 9.11
  • node 12.10.0
  • vue 3.12.0
  • sinon 7.5.0



エラー発生場所


p.368のログイン処理失敗のテストケース。
該当箇所のみ抜き出す。
describe('失敗', () => {
  beforeEach(() => {
    loginView = mount(KbnLoginView, {
      stubs: { 'kbn-login-form':  LoginFormComponentsStub },
      store,
      localVue
    })
    sinon.spy(loginView.vm, 'throwReject')
  })

  afterEach(() => {
    loginView.vm.throwReject.restore()
  })

  it('エラー処理が呼び出されること', done  => {
    const  message = 'login failed'
    actions.login.rejects(new  Error(message)) # このrejectsのエラーがcatchできず困っていた
    triggerLogin(loginView, LoginFormComponentsStub)

    loginView.vm.$nextTick(() => {
      const  callInfo = loginView.vm.throwReject
      expect(callInfo.called).to.equal(true)
      expect(callInfo.args[0][0].message).to.equal(message)
      done()
    })
  })
})


一箇所だけコメントを入れているが、そこのエラーがハンドリングできず、UnhandledPromiseRejectionWarningが発生していた。
エラーはthrowRejectメソッドで投げられ、throwRejectはコメントの次の行のtriggerLogin内で呼ばれるのだが、
triggerLoginをtry-catchで囲んでもうまくいかず、どうすればハンドリングできるのかかなり悩んだ。



解決できた方法


該当箇所のみ抜き出す
it('エラー処理が呼び出されること', done => {
  const message = 'login failed'
  actions.login.rejects(new Error(message))
  triggerLogin(loginView, LoginFormComponentsStub)

  loginView.vm.$nextTick(() => {
    loginView.vm.$nextTick().then(() => { # nextTickが追加されるのは別件のためここでは割愛
      const callInfo = loginView.vm.throwReject
      expect(callInfo.called).to.equal(true)
      expect(callInfo.args[0][0].message).to.equal(message)
      callInfo.returnValues[0].catch(err => { # sinon.spyから戻り値を取得し、catchする
        expect(err.message).to.equal(message)
      }).then(done)
    })
  })
})


タイトルにもある通り、sinon.spyを使用して解決した。
元々、throwRejectはsinon.spyを使用してラップされていたため、
戻り値を取得することができ、catchすることができた。



終わりに


一番の感想は、sinonすごい。
初めて使ったが、できることが色々あって、これなら色んなパターンのテストにも対応できそう。
ただ、テストだから仕方ないとはいえ、本当にこの解決方法が正解なのかはよくわからない。
もっと正しい方法がある気もする。
ご存知の方いたら教えてくださいm(__)m

しかしこの本、初版の発行が2018/10/6の割には、色々バージョンが古すぎる気がする。
入門書なのだから、できるだけ最新バージョンで書くべきだと思うのだが・・・
javascriptの進化が早すぎて、難しいのだろうか・・・


Vue.js入門 基礎から実践アプリケーション開発まで

0 件のコメント:

コメントを投稿