0

Suppose I create an object using a constructor:

function MyConstructor() {
  this.myMethod = () => console.log('foo');
}

const myObject = new MyConstructor();

And now in my test file I want to stub the myMethod method. If I had defined myMethod on the prototype, this would be pretty straightforward. One could just use:

sinon.stub(MyConstructor.prototype, 'myMethod')

But this doesn't work when the method is defined in the constructor using this, as in the example above.

This is an issue that's hard to avoid because some 3rd-party libraries define instance methods in this way, i.e., within the constructor instead of on the prototype. And we need a way to stub such methods when testing.

zjmiller
  • 2,709
  • 4
  • 29
  • 30
  • 1
    Just stub it on the instance you're testing? – Bergi Jul 25 '17 at 20:38
  • The instance is created in a different file though. Is there a way to do that in that case? – zjmiller Jul 25 '17 at 21:05
  • If you insist on it, [there are a few ways to overwrite instance properties](https://stackoverflow.com/a/43726273/1048572), but really I would recommend to just export the stubbing function as a hook and call into it with the instance from where it is created for the test. – Bergi Jul 25 '17 at 21:10
  • I was hoping to find a way to do it without modifying the structure of the application code (which someone other than me is working on), but maybe that won't be possible. – zjmiller Jul 25 '17 at 21:10
  • 2
    `myObject.myMethod = () => console.log('foo');` doesn't function? – dandavis Jul 25 '17 at 21:10
  • @zjmiller If modifying the structure of the application code leads to higher testability, it's not a bad thing. Usually it shouldn't be necessary, assuming the code follows best practices already, but you haven't shown us your particular structure yet so I cannot comment on it. – Bergi Jul 25 '17 at 21:19
  • I really have a hard time understanding the issue here. Why can't you just stub the methods directly on the returned instance, just as @dandavis showed? – oligofren Jul 26 '17 at 21:24
  • The issue is that I didn't have access to the returned instance, I only had access to the class / constructor. I was having no trouble stubbing instance methods that were on the prototype. But then I needed to stub an instance method that wasn't on the prototype, just defined in the constructor. I was just wondering if there was anything I could do in that case, given that I didn't have access to the returned instance. – zjmiller Jul 27 '17 at 15:08
  • I think one thing I've learned from this exchange is that returned instances should be exported so that test files can import them in order to stub methods. – zjmiller Jul 27 '17 at 15:12

0 Answers0