20 expect - ranhs/soda-test GitHub Wiki
When writing unit-tests, usally to validate that all went right, we check values of our execution using the chai expect method. This page gives a list of possible ways to use expect. Note that this is not the full list, you need to look at chai documentation.
Soda-Topical automaticly extens the expect method with the plugins chai-as-promise and sinon-chai. This list includes also some of those extensions.
We will always starts with calling the expect method and passing it a value. On the return value of expect you can call many prperteis and methods. Each property and method, returns same type of expect object (in many cases the same object) that you can continue calling those properties and methods on it. Some of the properties/methods also validate something, casing the test to fail if the validation has failed. the chain callins of the properties and method can create a centence that will be easy to read and understand what it is checking.
In this page we'll give examples for common usages, explain what does this check on the value, and what is the checked value after this call.
expect(value1).to.equal(value2)
validation: The value of value1 is the same as the value of value2. If the case of reference value, it is the same reference.
result checked value: value1
synonym: you may use equals instead of equal
you may obmit or add the property to
expect(2).to.equal(2).to.equal(2)
const obj = {}
expect(obj).to.equal(obj)
expect(2).equals(2)
expect(value1).to.not.equal(value2)
validation The value of value1 is not the same as the value of value2. In the case of reference value, it is not the same refence.
result checked value: value2
expect(3).to.not.equal(2).to.equal(2)
expect({}).to.not.equal({})
expect(value1).to.deep.equal(value2)
validation: The value of value1 is the same as the value of value2. In the case of reference value, the values may or may not have the same refernce, but all their inner values are the same recursivly. Works for objects and arrays.
result checked value: value1 with deep flag still set.
expect(2).to.deep.equal(2).to.equal(2)
expect({a:2,b:'#'}).to.deep.equal({b:'#',a:2}).to.equal({a:2,b'#'})
expect(value1).to.not.deep.equal(value2)
validation: The value of value1 is different from the value of value2. In the case of reference value, the values are not the same refernce, and there is a different in their inner values. Works for objects and arrays.
result checked value: value2 with deep flag still set.
expect(3).to.not.deep.equal(2).to.equal(2)
expect({a:2,b:'#'}).to.not.deep.equal({a:3,b:'#'}).to.equal({a:3,b:'#'})
expect(obj).to.have.property(name)
expect(obj).to.have.property(name,value)
validation: The given obj has a property that is named name. If value specified, it also validate the property value is equal to value
result checked value: obj[name] or value
expect({a:2,b:'#'}).to.have.property('a').equal(2)
expect({a:2,b:'#'}).to.have.property('a',2)
expect({a:2,b:'#'}).to.have.property('b').not.equal('$')
expect(obj).to.not.have.property(name)
expect(obj).to.not.have.property(name,value)
validation: The given obj does not have a property that is named name. If value specified validation also satisfy if the obj have a preropty of name name but its value is not equal to value
result checked value: obj[name] with the not flag still set
(Note: you cannot cancel the not flag by using the not property again)
expect({a:2,b:'#'}).to.not.have.property('c')
expect({a:2,b:'#'}).to.not.have.property('c').to.equals('@')
expect({a:2,b:'#'}).to.not.have.property('b','@')
expect(var).to.be.a(type)
validation: The given var is of the given type. (type is a string that is the name of the JS type
result checked value: var
synonym: You may use an instead of a
You may obmit to.be
expect(12).to.be.a('number')
expect("12").to.be.a('string')
expect({}).to.be.an('object')
expect([]).to.be.an('array')
expect(objectInstance).to.be.instanceOf(classType)
validation: The given objectInstance is an object that is of the given classType
result checked value: objectInstance
synonym: You may use instanceof instead of instanceOf
class A {a: number = 1}
class B extends A {b: number = 2}
...
expect(new A()).to.be.instanceOf(A)
expect(new B()).to.be.instanceOf(B)
expect(new B()).to.be.instanceOf(A)
expect(new A()).to.not.be.instanceOf(B)
expect(new A()).to.be.instanceOf(A).to.be.an('object').to.have.property('a',1)
expect(2).to.equal(2)
expect(3).to.not.equal(2)
expect({a:2}).to.deep.equal({a:2})
expect({a:2,b:3}.to.not.deep.equal({a:2})
expect(value1).to.be.above(value2)
validation: value2 > value1
synonym: you may use greaterThan instead of above
expect(2).to.be.above(1)
expect(2).to.be.greaterThan(1)
expect(value1).to.be.below(value2)
validation: value2 < value1
synonym: you may use lessThan instead of above
expect(2).to.be.below(3)
expect(2).to.be.lessThan(3)
expect(result).to.equal(null)
But you can do this using chai proeprties for those values:
expect(result).to.be.null
expect(result2).to.not.be.null
Those are some of the supported special values:
expect(false).to.be.false
expect(true).to.be.true
expect(null).to.be.null
expect(undefined).to.be.undefined
expect({}).to.be.empty
expect([]).to.be.empty
expect(undefined).to.not.exist
expect(null).to.not.exist
expect(methodSpy).to.have.been.calledOnce
expect(methodStub).to.have.been.calledOnce
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that was called exacly one time since it was created/reset
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo once')
callDemo( @spy(ExpectTest, 'demo') demoSpy: SinonSpy): TR {
ExpectTest.demo()
expect(demospy).to.have.been.calledOnce
expect(demospy).to.have.been.calledOnce.calledOnce
}
expect(methodSpy).to.have.been.calledTwice
expect(methodStub).to.have.been.calledTwice
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that was called exacly 2 times since it was created/reset
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo twice')
callDemo( @spy(ExpectTest, 'demo') demoSpy: SinonSpy): TR {
ExpectTest.demo()
ExpectTest.demo()
expect(demospy).to.have.been.calledTwice
expect(demospy).to.have.been.calledTwice.not.calledOnce
}
expect(methodSpy).to.have.been.calledThrice
expect(methodStub).to.have.been.calledThrice
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that was called exacly 3 times since it was created/reset
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo 3 times')
callDemo( @spy(ExpectTest, 'demo') demoSpy: SinonSpy): TR {
ExpectTest.demo()
ExpectTest.demo()
ExpectTest.demo()
expect(demospy).to.have.been.calledThrice
expect(demospy).to.have.been.calledThrice.not.calledOnce
}
expect(methodSpy).to.have.been.called
expect(methodStub).to.have.been.called
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that was called at least once since it was created/reset
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo')
callDemo( @spy(ExpectTest, 'demo') demoSpy: SinonSpy): TR {
expect(demospy).to.not.have.been.called
ExpectTest.demo()
expect(demospy).to.have.been.called
ExpectTest.demo()
ExpectTest.demo()
expect(demospy).to.have.been.called.calledThrice
}
expect(methodSpy).to.have.been.calledWith(args)
expect(methodStub).to.have.been.calledWith(args)
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that had a call with the given arguments
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo1 with expected arguments')
callDemo( @spy(ExpectTest, 'demo1') demo1Spy: SinonSpy): TR {
ExpectTest.demo1(12,"a")
expect(demo1spy).to.have.been.calledWith(12,"a")
expect(demo1spy).to.have.been.calledOnce.calledWith(12)
ExpectTest.demo1(13,"b")
expect(demo1spy).to.have.been.calledWith(12,"a").calledWith(13,"b").calledTwice
}
expect(methodSpy).to.have.been.calledWithMatch(args)
expect(methodStub).to.have.been.calledWithMatch(args)
validation: The given methodSpy or methodStub is a SinonSpy or SinonStub that had a call with the given arguments. For object argument, you don't need to specify all properties to have a match
result checked value: methodSpy / methodStub
synonym: you may obmit to.have.been
@it('should call demo2 with expected arguments')
callDemo( @spy(ExpectTest, 'demo2') demo2Spy: SinonSpy): TR {
ExpectTest.demo2({a:'a',b:12},12)
expect(demo2spy).to.have.been.calledWithMatch({b:12},12)
expect(demo1spy).to.have.been.calledWithMatch({a:'a'}).calledOnce
}
expect(constructorSpy).to.have.been.calledWithNew
expect(constructorStub).to.have.been.calledWithNew
validation: The given constructorSpy or constructorStub is a class constructor that was called (using the new keyword)
result check value: constructorSpy / constructorStub
import { DerivedClass } from './class'
...
@it('should call DerivedClass with new keyword')
createDerviedClass( @spy('./class','DerviedClass') derivedclassSpy: SinonSpy): TR {
const dc = new DerivedClass()
expect(derivedclassSpy).to.have.been.calledWithNew
expect(dc).to.be.instanceOf(DerivedClass)
expect(derivedclassSpy).to.have.been.calledWithNew.calledOnce
}
await expect(promise).to.eventually.be.fulfilled
validation: The given promise is a promise. The action awaits for the promise to be resolved, and validate it is resolved. Validation fails if and when the promise is rejected.
result check value: promise with the eventually flag
await return value: the resolution value.
synonym: you may obmit to and/or be
when using fulfilled you may obmit eventually
await expect( Promise.resolve() ).to.eventually.be.fulfilled
await expect( Promise.resolve() ).to.eventually.be.fulfilled.fulfilled
const rv = await expect( Promise.resolve(12) ).to.eventually.be.fulfilled
expect(rv).to.equal(12)
await expect(promise).to.eventually.be.euqal(value)
validation: The given promise is a promise. The action awaits for the promise to be resolved, and validate it was resolved with the given value. Validation fails if and when the promise is rejected, or resolves with a differnt value.
result check value: promise with the eventually
await return value: the resolution value.
synonym: you may obmit to and/or be
await expect( Promise.resolve(12)).to.eventually.be.equal(12)
await expect( Promise.resolve(12)).to.eventually.be.equal(12).fulfilled
const rv = await expect( Promise.resolve(12) ).to.eventually.be.equal(12)
expect(rv).to.equal(12)
await expect(promise).to.eventually.be.rejected
validation: The given promise is a promise. The action awaits for the promise to be rejected, and validate it is rejected. Validation fails if and when the promise is resolved.
result check value: promise with the eventually flag, but resolved insted of rejected
await return value: the rejected value.
synonym: you may obmit to and/or be
when using rejected you may obmit eventually
await expect( Promise.reject() ).to.eventually.be.rejected
await expect( Promise.reject(12) ).to.eventually.be.rejected.to.equal(12)
const rv = await expect( Promise.reject(12) ).to.eventually.be.rejected
expect(rv).to.equal(12)
await expect(promise).to.eventually.be.rejectedWith(value)
validation: The given promise is a promise. The action awaits for the promise to be rejected, and validate it is rejected with the given value or with an Error object that its message property is value. Validation fails if and when promise is resolved, or rejected with differnt value.
result check value: promise with the eventually flag, but resolved instead of rejected)
await return value: the rejected value.
synonym: you may obmit to and/or be
when using rejected you may obmit eventually
await( Promise.reject('kuku') ).to.eventually.be.rejectedWith('kuku')
await( Promise.reject(new Error('kuku')) ).to.eventually.be.rejectedWith('kuku')
await( Promise.reject('kuku') ).to.eventually.be.rejectedWith('kuku').to.equal('kuku')
await( Promise.reject(new Error('kuku')) ).to.eventually.be.rejectedWith('kuku').to.have.property('message','kuku')
let rv = await( Promise.reject('kuku') ).to.eventually.be.rejectedWith('kuku')
expect(rv).to.equal(rv)
let rv = await( Promise.reject(new Error('kuku')) ).to.eventually.be.rejectedWith('kuku')
expect(rv).to.have.property('message','kuku')
You may get the return valeu on the await to get the resolved value, for more validations.
await expect(Promise.resolve(12)).to.eventually.equal(12)
await expect(Promise.resolve(13)).to.eventually.not.equal(12)
await expect(Promise.resolve({a:11})).to.eventually.exist
await expect(Promise.resolve({a:11})).to.eventually.be.an('object')
await expect(Promise.resolve({a:11})).to.eventually.have.property('a',11)
await expect(Promise.resolve(true)).to.eventually.be.true
await expect(Promise.resolve(100)).to.eventually.be.above(10)
const rv = await expect(Promise.resolve(100)).to.eventually.not.be.below(100)
expect(rv).to.equal(100)