Last active
May 8, 2022 09:29
-
-
Save osher/4a08b0c633e41919298f0f6ce9357b92 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
This is a better example that does a better job both in testing and in communicating the test-intent. | |
(with some skipped parts to keep things short) | |
*/ | |
const helper = require('./helper'); | |
const { user } = require('./fixture'); | |
const SUT = require('../lib/accounts'); | |
const Should = require('should'); | |
describe('lib/accounts - accounts service', () => { | |
describe('creating a new user', () => { | |
describe('when registering an already registered user', () => { | |
let err, result; | |
before(async () => { | |
//arrange | |
await helper.assureIsFound(user.admin.userName); | |
//act | |
try { | |
result = await SUT.create(user.admin.registerData); | |
} catch(e) { | |
err = e; | |
} | |
}); | |
after(() => helper.assureIsFound(user.admin.userName)); | |
it('should not succeed', () => { | |
Should.exist(err); | |
}); | |
it('should reject with a EAlreadyRegistered error', () => { | |
Should(err) | |
.be.an.Error() | |
.have.properties({ | |
code: 'EAlreadyRegistered', | |
userName: user.admin.userName, | |
}); | |
}); | |
}); | |
describe('when registering a new user', () => { | |
describe('and payload is valid', () => { | |
describe('and all goes well', () => { | |
let result, err; | |
before(async () => { | |
//arrange | |
await helper.accountCleared(user.noSuch.userName)); | |
//act | |
try { | |
result = SUT.create(user.noSuch.registerData); | |
} catch(e) { | |
err = e; | |
} | |
}); | |
after(() => helper.accountCleared(user.noSuch.userName)); | |
it('should not fail', () => Should.not.exist(err)); | |
describe('the yielded view', () => { | |
it('should inclode the expected profile data', () => Should(result).have.properties(users.noSuch.profileData)); | |
it('should include the dynamic/random properties', () => Should(result).have.properties(['id', 'salt', 'passwordSha'])); | |
}); | |
describe('the created user', () => { | |
let stored; | |
before(async () => { | |
stored = await helper.readAccount(user.noSuch.userName); | |
}); | |
it('should be created with all fields of the expected stored form', () => { | |
//TRICKY: mind random fields | |
Object.assign(stored, { salt: 'mock-salt', passwordSha: 'mock-passwordSha' }); | |
Should(stored).deepEql(users.noSuch.expectedStoredForm); | |
}); | |
}); | |
}); | |
describe('and db connection is lost', () => { | |
//Arrange - disrupt the connection using the connection-provider or using stubs | |
//Act - call SUT | |
//Assert - e.g - expect the right error code | |
//Aftermath - make sure any disruption is undone | |
}); | |
}); | |
}); | |
}); | |
describe('deleting a user', () => { | |
describe('when trying to delete a user', () => { | |
describe('and the db connection is lost', () => { | |
//disrupt the connection using the connection-provider or using stubs | |
//very like above... allow me to to repeat it here | |
}); | |
describe('and the user IS found in the db', () => { | |
let result, err; | |
before(async () => { | |
//arrange | |
await helper.assureAccountExistsAs(user.forDeletion.expectedStoredForm); | |
//act | |
try { | |
result = await SUT.close(user.forDeletion.userName); | |
} catch(e) { | |
err = e; | |
} | |
}); | |
after(() => helper.accountCleared(user.forDeletion.userName)); | |
it('should not fail', () => Should.not.exist(err)); | |
it('should yield the removed account', () => Should(result).have,properties(users.forDeletion.profileData)); | |
it('should mark the removed account as DELETED', () => Should(result).have.property('status', 'DELETED')); | |
}); | |
describe('and the user is NOT found in the db', () => { | |
// use fx.user.noSuch... | |
// assertion expects the correct error | |
}); | |
}); | |
}); | |
}); | |
/** | |
It is a better example because: | |
- it observes the holy-trinity-of-tests: The SUT, the Spec, and the Test-Code | |
- it observes organization by AAAA | |
- it test intents are reflected in test cases on the test-code AND on the fixture | |
- it assures a cleanup | |
- it assert every spec explicitly and declares the context of each assertion | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment