diff --git a/README.md b/README.md index a0404c9..b779424 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ In the extraordinarily unlikely event that you have an object in your data that ### Mock Session Generation -There are two functions for generating sessions that produce mock outptu. These can be used for confirming that output is what you expect it to be. +There are two functions for generating sessions that produce mock output. These can be used for confirming that output is what you expect it to be. ### Generation from a Query Set @@ -247,6 +247,32 @@ The `sessionRunMock` function should have as parameters `(query: string, params: In theory, you could create a session which emulates your entire database for all of the queries in your tests, and simply reuse the mock session in all of your tests. Note that you can also throw errors if you are testing for them. +### Testing Transactions + +Transactions can be called in your test as easily as directly calling `.run()`. + +For instance: + +```typescript + const session = mockSessionFromQuerySet(querySet) + const output: any = await session.readTransaction((tx: any) => + tx.run(query, params)) + // assert that output is expected +``` + +If you want to ensure that a particular transaction type was executed, you can look at `summary.transactionType` in the output. The value of `transactionType` will be either `READ` or `WRITE`. + +For instance: + +```typescript + const session = mockSessionFromFunction(sessionRunMock) + + const output: any = await session.writeTransaction((tx: any) => + tx.run('', { foo: "bar" })) + + t.is(output.summary.transactionType, 'WRITE') +``` + ### Mock Driver Generation There are cases where you will have to generate a mock driver. The most typical use case is for mocking an Apollo Server that uses the [@neo4j/graphql](https://www.npmjs.com/package/@neo4j/graphql) library. diff --git a/src/custom/session/mockSessionFromFunction.ts b/src/custom/session/mockSessionFromFunction.ts index 4226dd5..fa31751 100644 --- a/src/custom/session/mockSessionFromFunction.ts +++ b/src/custom/session/mockSessionFromFunction.ts @@ -19,10 +19,15 @@ export function mockSessionFromFunction(mockRun: Function): Session { const fakeSession = driver.session() fakeSession.run = mockRun - const mockBeginTransaction = () => { + + const mockBeginTransaction = (transactionType: string) => { let _isOpen = true; return { - run: mockRun, + run: async (query: string, params: any) => { + const output = await mockRun(query, params) + output.summary.transactionType = transactionType + return output + }, commit: () => { _isOpen = false; return Promise.resolve() diff --git a/src/custom/session/mockSessionFromQuerySet.ts b/src/custom/session/mockSessionFromQuerySet.ts index e166c6b..13cd5cd 100644 --- a/src/custom/session/mockSessionFromQuerySet.ts +++ b/src/custom/session/mockSessionFromQuerySet.ts @@ -50,21 +50,13 @@ function mockSessionFromQuerySet(querySet: QuerySpec[]): Session { const mockRun = async (query: string, params: any) => { let queryMatched = false; - // querySet.map((querySpec: QuerySpec) => { - // if (removeExtraWhite(querySpec.query) === removeExtraWhite(query)) { - // queryMatched = true; - // if (!querySpec.params || isSubset(params, querySpec.params)) { // was: JSON.stringify(querySpec.params) === JSON.stringify(params) - // output = storedToLive(querySpec.output); - // } - // } - // }); for (let index = 0; index < querySet.length; index++) { const querySpec: QuerySpec = querySet[index]; if (removeExtraWhite(querySpec.query) === removeExtraWhite(query)) { queryMatched = true; - if (!querySpec.params || isSubset(params, querySpec.params)) { + if (!querySpec.params || isSubset(params, querySpec.params)) { return storedToLive(querySpec.output); } } @@ -79,10 +71,14 @@ function mockSessionFromQuerySet(querySet: QuerySpec[]): Session { throw new Error(errorMessageNoMatchedQuery); }; - const mockBeginTransaction = () => { + fakeSession._beginTransaction = function mockBeginTransaction(transactionType: string) { let _isOpen = true; return { - run: mockRun, + run: async (query: string, params: any) => { + const output = await mockRun(query, params) + output.summary.transactionType = transactionType + return output + }, commit: () => { _isOpen = false; return Promise.resolve(); @@ -93,10 +89,10 @@ function mockSessionFromQuerySet(querySet: QuerySpec[]): Session { }, isOpen: () => _isOpen, }; - }; + } fakeSession.run = mockRun; - fakeSession._beginTransaction = mockBeginTransaction; + // fakeSession._beginTransaction = mockBeginTransaction; return fakeSession; } diff --git a/test/custom/mockSessionFromFunction.test.ts b/test/custom/mockSessionFromFunction.test.ts index 6bfe312..bd13a78 100644 --- a/test/custom/mockSessionFromFunction.test.ts +++ b/test/custom/mockSessionFromFunction.test.ts @@ -1,8 +1,8 @@ import test from 'ava' const mockSessionFromFunction = require("../../src/custom/session/mockSessionFromFunction") // import { mockSessionFromFunction} from "../../src/custom/session/mockSessionFromFunction" -import {sampleRecordList} from "./data/sampleRecordList"; -import {dataToLive} from "../../src/custom/response/dataToLive"; +import { sampleRecordList } from "./data/sampleRecordList"; +import { dataToLive } from "../../src/custom/response/dataToLive"; const sessionRunMock = (query: string, params: any) => { return dataToLive(sampleRecordList); @@ -11,13 +11,23 @@ const sessionRunMock = (query: string, params: any) => { test('mockSessionFromFunction', t => { const session = mockSessionFromFunction(sessionRunMock) t.is(session.run, sessionRunMock) - t.not(session.run, ()=>{return 1}) + t.not(session.run, () => { return 1 }) }) +test('mockSessionFromFunction works with transacation', async t => { + const session = mockSessionFromFunction(sessionRunMock) + + const output: any = await session.writeTransaction((tx: any) => + tx.run('', { foo: "bar" })) + + t.is(output.summary.transactionType, 'WRITE') +}) + + test('mockSessionFromFunction with transacation', async t => { const session = mockSessionFromFunction(sessionRunMock) const tx = session._beginTransaction() - t.is(tx.run, sessionRunMock) + // t.is(tx.run, sessionRunMock) t.is(tx.isOpen(), true) t.is(await tx.rollback(), await Promise.resolve()) t.is(await tx.commit(), await Promise.resolve()) diff --git a/test/custom/mockSessionFromQuerySet.test.ts b/test/custom/mockSessionFromQuerySet.test.ts index 11e45f4..3df8624 100644 --- a/test/custom/mockSessionFromQuerySet.test.ts +++ b/test/custom/mockSessionFromQuerySet.test.ts @@ -72,6 +72,40 @@ const expectedOutput3 = { ] } +const expectedOutput4: StoredResponse = { + records: + [ + { + "keys": [ + "role" + ], + "length": 1, + "_fields": [ + "Moderator" + ], + "_fieldLookup": { + "role": 0 + } + }, + { + "keys": [ + "role" + ], + "length": 1, + "_fields": [ + "customer" + ], + "_fieldLookup": { + "role": 0 + } + } + ], + summary: { + transactionType: 'READ' + } +} + + const query = 'foo' const query2 = 'foobaroo' const noParamsQuery = 'noparams' @@ -109,6 +143,15 @@ test('mockSessionFromQuerySet returns correct output', async t => { t.deepEqual(stripUpdates(output), stripUpdates(storedToLive(expectedOutput))) }) + +test('mockSessionFromQuerySet works called with transaction', async t => { + const session = mockSessionFromQuerySet(querySet) + const output: any = await session.readTransaction((tx: any) => + tx.run(query, params)) + + t.like(stripUpdates(output), stripUpdates(storedToLive(expectedOutput4))) +}) + test('mockSessionFromQuerySet returns correct output even with extra params', async t => { const session = mockSessionFromQuerySet(querySet) const output = await session.run(query, { 'boo': 'bar', 'extra': 'should be ignored' }) @@ -125,11 +168,11 @@ test('mockSessionFromQuerySet evaluates in order', async t => { const session = mockSessionFromQuerySet(querySet) // this will match the first query result - const output = await session.run(query2, { 'x': 'y'}) + const output = await session.run(query2, { 'x': 'y' }) t.like(stripUpdates(output), stripUpdates(storedToLive(expectedOutput))) // this will match the second query result - const output2 = await session.run(query2, { 'x': 'z'}) + const output2 = await session.run(query2, { 'x': 'z' }) t.like(stripUpdates(output2), stripUpdates(storedToLive(expectedOutput3))) }) @@ -138,7 +181,7 @@ test('mockSessionFromQuerySet evaluates in order', async t => { test('mockSessionFromQuerySet takes no params', async t => { const session = mockSessionFromQuerySet(querySet) const output = await session.run(noParamsQuery) - t.like(stripUpdates(output), stripUpdates(storedToLive(expectedOutput2)) ) + t.like(stripUpdates(output), stripUpdates(storedToLive(expectedOutput2))) // t.like(output, storedToLive(expectedOutput2)) })