4

I've got an object like this:

var obj = {
    "uuid": "60afc3fa-920d-11e5-bd17-b9db323e7d51",
    "type": "candy"
}

I want to write a test that checks first that the object has the property 'uuid' in the first place, and then that 'uuid' is a specific length (36 chars).

Trying this doesn't work

obj.should.have.property('uuid').which.should.have.length(36)

It fails with:

Uncaught AssertionError: expected Assertion {
  obj: '60afc3fa-920d-11e5-bd17-b9db323e7d51',
  params: { operator: 'to have property \'uuid\'' },
  negate: false } to have property 'length' of 36 (got [Function])

And this (which actually doesn't make syntactic sense anyway - since it would apply to the parent object not the value)

obj.should.have.property('uuid').and.be.length(36)

Which fails with:

Uncaught TypeError: usergridResponse.entity.should.have.property(...).which.should.be.equal.to is not a function

Even this doesn't work:

obj.should.have.property('uuid').which.equals('60afc3fa-920d-11e5-bd17-b9db323e7d51')

So what's the correct way to chain assertions on the property of an object?

brandonscript
  • 68,675
  • 32
  • 163
  • 220

2 Answers2

3

I think that this could be the better option:

var session = {
    "uuid": "60afc3fa-920d-11e5-bd17-b9db323e7d51",
    "type": "candy"
};

session.should.have.property('uuid').with.a.lengthOf(36);

Or this if you want to choose should twice, but I don't think that this is a proper way (explained bellow).

var session = {
    "uuid": "60afc3fa-920d-11e5-bd17-b9db323e7d51",
    "type": "candy"
};

session.should.have.property('uuid').which.obj.should.have.length(36);

You can see them working here:

https://jsfiddle.net/Lz2zsoks/

.an, .of, .a, .and, .be, .have, .with, .is, .which are just chainers that don't do nothing.

Update

As a response to @denbardadym I'll try to explain why you should not use should twice:

  • You won't use it twice in natural language, so it's better to don't use it in tests
  • Should.js is not intended to be used in that way. You will not find any example of that usage in the library documentation.
artberri
  • 1,327
  • 13
  • 26
  • It is not right way to suggest use .should twice - better to explain why it is wrong. – den bardadym Nov 23 '15 at 19:19
  • Ok, already explained. But it is also not right way to write an answer without giving an answer ;) – artberri Nov 23 '15 at 19:30
  • Also the obj shouldn't be length 36, obj.uuid should be – brandonscript Nov 23 '15 at 19:38
  • @remus The first option I'm giving you works and I guess it has a proper syntactic. The second one is checking the length of the property not the object, I understand it fine. `.obj` is the way to access the property value, if you see my answer I changed the name of your ariable `obj` to `session`. – artberri Nov 23 '15 at 19:48
  • Definitely your first suggestion is what I was looking for. And I can also use that with `.equal('...')` (instead of `.with.a.lengthOf`) – brandonscript Nov 23 '15 at 19:51
  • 1
    For clarity, I ended up with: `obj.should.be.an.Object.and.have.property('uuid').with.a.lengthOf(36)` – brandonscript Nov 23 '15 at 20:05
  • 1
    To try to continue helping: obj.should.be.an.Object is not asserting nothing, you needto use the function (I think that the doc is wrong, if you don't do obj.should.be.an.Object() it will not work) Check this fiddle: https://jsfiddle.net/a1ds5q99/ – artberri Nov 23 '15 at 20:21
  • Also, I would remove totally the object assertion because in Javascript there are a lot of things that are instances of an Object (like arrays), so anything that can have a property will assert to true if you check if it's an Object. – artberri Nov 23 '15 at 20:23
1

First statement failed because you call .should twice - second time you assert on assertion, it should be:

obj.should.have.property('uuid').which.have.length(36)

(error message literally sais, that Assertion {...} has no property length)

Second statement does not throw for me:

obj.should.have.property('uuid').and.be.length(36)

(your error message looks like not that assertion fail for you)

Last statement - there is not .equals assertion - it should be .equal. And it of cause throws for me because "0320a79a-920d-11e5-9b7a-057d4ca344ba" !== "60afc3fa-920d-11e5-bd17-b9db323e7d51"

Hope it helps.

den bardadym
  • 2,747
  • 3
  • 25
  • 27
  • Think I'm making progress. Uuid not matching was a copy fail on my part . `.length` is probably because it's `.lengthOf` instead of `.length`. Will fiddle some more. – brandonscript Nov 23 '15 at 19:12
  • That is ok =). I suggest you for such question use gitter chat for should.js repo, i usually answer faster. – den bardadym Nov 23 '15 at 19:14