Is there a way to get Jasmine to generate spies so that such a test will pass:
it('a', function () {
const a = jasmine.createSpyObj('a', ['b', 'c.d', 'e.f.g']);
a.b();
a.c.d();
a.e.f.g();
expect(a.b).toHaveBeenCalled();
expect(a.c.d).toHaveBeenCalled();
expect(a.e.f.g).toHaveBeenCalled();
});
the use case for this is reducing the typing required to create such nested spies
There is no jasmine api that will create this easily for you. You need to create the spies directly, something like this is the best you can get:
const a = jasmine.createSpy().and.returnValue({
b: jasmine.createSpy(),
c: jasmine.createSpy().and.returnValue({
d: jasmine.createSpy()
}),
e: jasmine.createSpy().and.returnValue({
d: jasmine.createSpy().and.returnValue({
f: jasmine.createSpy()
})
})
});
If you need to do this often, then I'd recommend that you create some sort of function that can recursively extract a spy description and generate a nested spy object from it. But, there is nothing native in Jasmine that does this for you.
Related
I've found this function in an assemblyscript project for a NEAR contract:
export function assert_single_promise_success(): void {
const x = ContractPromise.getResults()
assert(x.length == 1, "Expected exactly one promise result")
assert(x[0].succeeded, "Expected PromiseStatus to be successful")
}
What does ContractPromise.getResults() do exactly? How should implement the same thing in rust?
here is something similar in Rust from one of the examples in the SDK repo
require!(env::promise_results_count() == 2);
let data0: Vec<u8> = match env::promise_result(0) {
PromiseResult::Successful(x) => x,
_ => env::panic_str("Promise with index 0 failed"),
};
I'm going to give an answer, comments taken directly from the implementation of ContractPromise.getResults(), which can be found here. The implementation also has an example on how to use the function, which may be useful.
Method to receive async (one or multiple) results from the remote
contract in the callback.
#returns An array of results based on the number of promises the
callback was created on. If the callback using then was scheduled
only on one result, then one result will be returned.
I'm looking at this this page about various shorthand syntaxes in ES6 for declaring methods inside of objects.
I'm not understanding the differences between these two forms:
var foo = {
a() {},
b() {}
};
and
var foo = {
x: (y) => y
};
The article seems to make a clear distinction between these two formats, but doesn't the first one really just become the second? If we wanted to include parameters, we'd just do a(y) {} in the first one.
but doesn't the first one really just become the second?
No. The method syntax is more equivalent to using a function expression:
var foo = {
a: function() {},
};
If you'd assign an arrow function then you won't be able to access the object via this.
And of course an empty function (function() {}) is not the same as the identity function (function(x) { return x; }).
See also
Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?
Methods in ES6 objects: using arrow functions
What is the difference between
jasmine.createSpy('someMethod')
And
spyOn(someObject, 'someMethod')
And why should one choose to use spyOn?
My guess is that the first alternative will match the method someMethod no matter in what object it's contained but spyOn will only match if it's contained in someObject. Thus making createSpy just a more generic matcher?
The difference is that you should have a method on the object with spyOn
const o = { some(): { console.log('spied') } };
spyOn(o, 'some');
while the mock method is created for your with createSpy():
const o = {};
o.some = jasmine.createSpy('some');
The advantage of the spyOn is that you can call the original method:
spyOn(o, 'some').and.callThrough();
o.some(); // logs 'spied'
And as #estus says the original method is restored after the test in case of spyOn. This should be done manually when it's reassigned with.
Additionally to the other fine answer:
Use spyOn() to spy (intercept) an existing method on an object to track calls of other modules to it.
Use jasmine.createSpy() to create a function that can be passed as callback or Promise handler to track call-backs.
I have a test case like this:
it("test",function(){
var spy = sinon.spy(test,"method");
decider = 1
test.nextServiceTab();
assert(spy.calledOnce);
});
When the method test.nextServiceTab is called, it calls method based on the value decider, which is supposed to be 1. In fact the control goes to the the method.
But why does the control goes to the method? Since I'm spying it should't be right?
My goal was to just check that method is called. Where I'm making mistake?
Is the way I have used sinon is correct?
If you want to avoid control entering the function, you should use sinon.stub instead of sinon.spy. With a stub you can still see if it is called because stub implements the same interface as spy, but additionally it prevents the original function from receiving control and allows you to override the behavior.
For example, if you want the function to always return true:
it("test",function(){
var stub = sinon.stub(test, "method");
stub.returns(true);
decider = 1;
test.nextServiceTab();
assert(stub.calledOnce);
stub.restore();
});
I'm using mocha and chai as assertions.
I have several assertions in my spec:
Exp1.should.be.true
Exp2.should.be.true
Exp3.should.be.true
If one of them fails mocha writes "expected false to be true". Is there a way to identify them?
With expect I can do it:
expect(Exp1, 'Exp1').to.be true
Is something like this possible with should?
Apparently should does not support custom error messages at the moment.
You can create your own helper for setting the message:
var chai = require('chai'),
should = chai.should();
// Helper definition - should be in a shared file
chai.use(function(_chai, utils) {
_chai.Assertion.addMethod('withMessage', function(msg) {
utils.flag(this, 'message', msg);
});
});
// Sample usage
it('should fail', function() {
var Exp1 = false;
var Exp2 = false;
Exp1.should.be.withMessage('Exp1').true;
Exp1.should.withMessage('Exp2').be.true;
});
I checked the chai code with respect to should and found that the currently accepted answer is either incorrect or incomplete.
If you read there, you will find that there is indeed a way to include your own custom message in each assertion. The catch is that you may need to change your assertion syntaxes to use should's function calls instead.
(1).should.equal(0, 'This should fail');
/****** Output with (I believe) default reporter *****
* This should fail
* + expected - actual
*
* -1
* +0
*/
Note that your output may look different if you are using your own reporter. If you feel so inclined, you could probably wrap should's functions to always include line number in your assertion output.
I wonder why they don't simply add which line fired the assertion, but I ran into this exact same problem myself. A colleague who can manuals better than I noted there is a setting for includeStack which will give line numbers for assertions.
http://chaijs.com/guide/styles/#configure
Since I'm doing a lot of async, I might run my tests in before or beforeEach and then run a separate it for each assertion.