vuejs / vue-rx

👁️ RxJS integration for Vue.js.
MIT License
3.35k stars 190 forks source link

$watchAsObservable not being fired in unit tests #51

Open syonip opened 7 years ago

syonip commented 7 years ago

I am testing with karma, and I've notice this.$watchAsObservable('text') doesn't emit values even though this.text has changed. Thanks.

The test:

it('should be saved after timeout', (done) => {
      const saveFileSpy = sinon.spy()
      const EditorWithMocks = EditorInjector({
        '../../../api/file-access': {
          saveFile: saveFileSpy
        }
      })

      const vm = createVm(EditorWithMocks)

      vm.text = 'pepo'
      vm.filePath = 'filepath'

      const inputTextArea = vm.$el.querySelector('.input-textarea')
      inputTextArea.textContent = 'p'
      dispatchInputEvent(inputTextArea)

      clock.tick(1000)
      Vue.nextTick()
        .then(() => {
          expect(saveFileSpy).to.have.been.calledWith('pepop', '123', 'filepath')
          done()
        })
        .catch(done)

The code:

saveFileSubscription: this.$watchAsObservable('text')
        .pluck('newValue')
        .debounceTime(settings.autoSaveTimeout)
        .distinctUntilChanged()
        .do(() => this.saveFile()),
regou commented 7 years ago

@syonip Could you provide more detail about how the vm was constructed? Btw I'm not sure sinon.spy() can work will with vue's reactive data system.

syonip commented 7 years ago

Thanks for helping.

Here is the vm creation function:

import Vue from 'vue'
import vuenit from 'vuenit'
const EditorInjector = require('!!vue-loader?inject!renderer/components/MainPageView/Editor.vue')

function createVm(mockedComp) {
  const EditorWithMocks = EditorInjector({
    '../../../api/file-access': {
      saveFile: sinon.stub()
    }
  })
  mockedComp = mockedComp || EditorWithMocks

  const { $router } = vuenit.mockRouter()

  const $store = vuenit.store({
    getters: {
      mainPassword() {
        return '123'
      }
    }
  })

  const options = {
    inject: {
      $router,
      $store
    },
    stubComponents: true
  }
  const vm = vuenit.mount(mockedComp, options)
  return vm
}

I don't think it's to do with sinon.spy, because this test used to pass before I changed the implementation to use vue-rx.

UrsMetz commented 7 years ago

There is also an issue concerning Angular, RxJS observables, and unit tests (angular/angular#10127) where some observables don't fire when the clock is mocked. In that issue there are some workarounds described and also an explanation why this happens with a mocked clock. I couldn't completely verify this because at some point I got lost in RxJS's source code but the explanation sounds reasonable.

printjs commented 6 years ago

@syonip I'm testing karma.I 'm using typescript. But the TS2339 occur when I use vueRx