4

I am using Sinon to stub API calls when unit testing my components (written with TypeScript and vue-class-component). After adding the stub to the unit test, the original method is still being called (not returning the stubbed value).

it('should set the text to bar', async () => {

  const stubbedApiResponse = () => {
    return 'bar';
  };

  sinon.stub(MyComponent.prototype, 'getFoo').callsFake(stubbedApiResponse);

  let options = {
    template: '<div><my-component></my-component></div>',
    components: {'my-component': MyComponent},
    store: this.store
  };
  this.vm = new Vue(options).$mount();

  Vue.nextTick(() => {
    expect(this.vm.$el.querySelector('.text').textContent).toBe('bar'); // Still equals 'foo'
  });
});

The method that I am attempting to stub is called on mounted in the component and sets the text content. Any help would be appreciated, thanks!

cfly24
  • 1,882
  • 3
  • 22
  • 56

1 Answers1

1

The problem was that, when using TypeScript classes with vue-class-component, the methods live inside the options property of the exported class so, to stub a method, you have to do it like this:

sinon.stub(MyComponent.options.methods, 'getFoo').callsFake(stubbedApiResponse)

In case your test passes doing that change, ignore everything below.


I see a couple of unrelated problems in the code:

  • When using PhantomJS, then there's no point in using async since Vue.nextClick won't use Promises anyway; it's simpler to use the done function provided by mocha:

    it('...', (done) => {
      // ...
      Vue.nextTick(() => {
        // ...
        done()
      }
    }
    
  • chai's be is a chain and doesn't test for equality; equal should be used, eg: expect(foo).to.equal('bar').

  • It's better to leave vm as a variable instead of a property to avoid referential headaches:

    const vm = //...
    nextTick(() => { expect(vm.$el)//... }
    
Luis Orduz
  • 2,887
  • 1
  • 13
  • 19
  • I should've mentioned this in the initial post (besides the tag), but I'm using Typescript and the Vue class component decorator, so the methods aren't inside `methods`. They are just instance methods on the class. – cfly24 Oct 21 '17 at 05:31
  • Updated answer, taking in account typescript classes. – Luis Orduz Oct 25 '17 at 20:31