diff --git a/code/in-search-of-a-unit/test/Auction.test.ts b/code/in-search-of-a-unit/test/Auction.test.ts index 5539a54..0a81743 100644 --- a/code/in-search-of-a-unit/test/Auction.test.ts +++ b/code/in-search-of-a-unit/test/Auction.test.ts @@ -4,6 +4,7 @@ import { Money } from "../src/Money"; import * as uuid from 'uuid'; import { Offer } from "../src/Offer"; import * as assert from "assert"; +import * as sinon from "sinon"; function testOffer(amount: number, currency = 'PLN', user?: string): Offer { return { @@ -26,25 +27,36 @@ function stuffAuction(auction: Auction, count: number) { describe('Auction', function() { it('should immediately reject an offer that could not possibly win', async function() { const notifier = new EmailNotifier(); + const mockNotifier = sinon.mock(notifier); const sale = new Auction('PLN', 5, notifier); // Initially, everybody goes into auction at 10 PLN: const initialOffers = stuffAuction(sale, 5); // Subsequent offers for the same amount should be rejected: - const sixthOfferResult = await sale.makeOffer(testOffer(10)); - assert.strictEqual(sixthOfferResult, false); + const sixthOffer = testOffer(10); + mockNotifier.expects('notifyUser').once().withArgs(sixthOffer.madeByUserID, { + eventType: 'outbid', + offer: sixthOffer + }).resolves(); + const sixthOfferResult = await sale.makeOffer(sixthOffer); + mockNotifier.verify(); }); it('should replace the last offer if a better one comes in', async function() { const notifier = new EmailNotifier(); + const mockNotifier = sinon.mock(notifier); const sale = new Auction('PLN', 5, notifier); const initialOffers = stuffAuction(sale, 5); // A new offer should annul the last one made: const lastOffer = sale.getQualifyingOffers().pop()!; const betterOffer = testOffer(15); + mockNotifier.expects('notifyUser').once().withArgs(lastOffer.madeByUserID, { + eventType: 'outbid', + offer: lastOffer + }).resolves(); await sale.makeOffer(betterOffer); - assert.ok(sale.getQualifyingOffers().includes(betterOffer)); - assert.ok(!sale.getQualifyingOffers().includes(lastOffer)); + mockNotifier.verify(); }); it('should select the winners after some offers are replaced', async function() { + // TODO: Rewrite this test to use behavior verification as well! const notifier = new EmailNotifier(); const sale = new Auction('PLN', 5, notifier); const initialOffers = stuffAuction(sale, 5); diff --git a/code/package-lock.json b/code/package-lock.json index 021401b..113b742 100644 --- a/code/package-lock.json +++ b/code/package-lock.json @@ -62,6 +62,21 @@ "integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==", "dev": true }, + "@types/sinon": { + "version": "9.0.8", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.8.tgz", + "integrity": "sha512-IVnI820FZFMGI+u1R+2VdRaD/82YIQTdqLYC9DLPszZuynAJDtCvCtCs3bmyL66s7FqRM3+LPX7DhHnVTaagDw==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", + "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", + "dev": true + }, "@types/uuid": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz", diff --git a/code/package.json b/code/package.json index cf2cade..106ae5a 100644 --- a/code/package.json +++ b/code/package.json @@ -19,6 +19,7 @@ "@types/big.js": "^6.0.0", "@types/mocha": "^8.0.4", "@types/node": "^14.14.7", + "@types/sinon": "^9.0.8", "@types/uuid": "^8.3.0", "ts-node": "^9.0.0", "typescript": "^4.0.5"