Closed tusharmath closed 10 years ago
Found the solution - Q.Promise needs to be passed to sinonAsPromised
Correct. You need to pass a Promise
constructor. If you're working on a new library, you should consider choosing a promise library with a better API and stronger feature set (Bluebird).
@bendrucker I am looking for a Promise framework which has a self contained mocking module to manage tests more efficiently. Not sure if bluebird is capable of doing so.
I have no clue what you mean by that. An example would be helpful.
My apologies for not being clear. The problem is that I wanted to use a module which makes my tests Synchronous. The fact that I am using a promise everywhere is making my code very difficult to test. If there was a Promise Library which would make all my code Sync it would be super easy.
For Example
#Stub the create method which will be called by @mod._create
@crudP.cruds.FakeResource.create = sinon.stub().rejects error
#Calling the method under test (Making sure the test returns a promise)
@mod._create @req, @res
.then =>
# The worst part is putting this piece of code inside a callback
@res.send.calledWith error
.should.be.ok
Angular requires you to flush $q
promises synchronously. That's because those promises need to integrate with the digest cycle. Bluebird does allow you to use a custom scheduler and to my knowledge it is the only library capable of that sort of behavior. That said, I'd highly recommend against going down that route. There's no need and it just adds a bunch of complexity. Promises are not difficult to test. Mocha supports returning promises from your tests. Combine that with Bluebird's bind
method instead of relying on CoffeeScript to generate a closure and sinon-chai
and you can make your test a whole lot more readable and useful.
it('should call res.send with the error', function () {
sinon.stub(this.crudP.cruds.FakeResource, 'create').rejects(error);
return this.mod_create(this.request, this.response)
.bind(this)
.then(function () {
this.res.send.should.have.been.calledWith(error);
});
});
That’s yet another approach that I tried. The biggest challenge is - what happens if this.mod_create()
doesn’t return a promise? As in, though it is using promises internally, I don’t have access to them thru any public method/property. In such a scenario, I have two options
What are your thoughts?
Regards, Tushar Mathur tusharmath@gmail.com tusharm.com http://tusharm.com/ +91 96-20-826576
On Oct 31, 2014, at 10:21 PM, Ben Drucker notifications@github.com wrote:
Angular requires you to flush $q promises synchronously. That's because those promises need to integrate with the digest cycle. Bluebird does allow you to use a custom scheduler https://github.com/petkaantonov/bluebird/blob/master/API.md#promisesetschedulerfunction-scheduler---void and to my knowledge it is the only library capable of that sort of behavior. That said, I'd highly recommend against going down that route. There's no need and it just adds a bunch of complexity. Promises are not difficult to test. Mocha supports returning promises from your tests. Combine that with Bluebird's bind method instead of relying on CoffeeScript to generate a closure and sinon-chai and you can make your test a whole lot more readable and useful.
it('should call res.send with the error', function () { sinon.stub(this.crudP.cruds.FakeResource, 'create').rejects(error); return this.mod_create(this.request, this.response) .bind(this) .then(function () { this.res.send.should.have.been.calledWith(error); }); }); — Reply to this email directly or view it on GitHub https://github.com/bendrucker/sinon-as-promised/issues/4#issuecomment-61291252.
Unless there's a very good reason you should not use promises "internally" like you'd use a library like async to coordinate some callbacks. You should always be chaining things. Trying to manually resolve a bunch of hard to reach promises in testing is just going to make your tests brittle.
I am trying to make it work with Q and unfortunately its not working.
Error thrown