Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1806 new net p1 adding a reusable mock http client for unit tests #1868

Open
wants to merge 3 commits into
base: feature-thorest
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,38 +1,26 @@
import { describe, test, expect } from '@jest/globals';
import { type FetchHttpClient } from '../../../src/http';
import {
type RawBlockResponseJSON,
RawBlockResponse,
RetrieveRawBlock
} from '../../../src/thor/blocks';
import { Revision } from '@vechain/sdk-core';

const mockHttpClient = <T>(response: T): FetchHttpClient => {
return {
get: jest.fn().mockImplementation(() => {
return {
json: jest.fn().mockImplementation(() => {
return response;
})
};
})
} as unknown as FetchHttpClient;
};
import { mockHttpClient } from '../../utils/MockUnitTestClient';

/**
* VeChain raw block - unit
*
* @group unit/block
*/
describe('RetrieveBlock unit tests', () => {
test('should obtain raw block successfully', async () => {
test('should obtain raw block successfully 2', async () => {
const mockRawBlock: RawBlockResponseJSON = {
raw: '0x123'
} satisfies RawBlockResponseJSON;

const mockRawBlockResponse = await RetrieveRawBlock.of(
Revision.BEST
).askTo(mockHttpClient<RawBlockResponseJSON>(mockRawBlock));
).askTo(mockHttpClient(mockRawBlock, 'get'));
expect(mockRawBlockResponse.response.toJSON()).toEqual(
new RawBlockResponse(mockRawBlock).toJSON()
);
Expand All @@ -43,8 +31,9 @@ describe('RetrieveBlock unit tests', () => {

await expect(
RetrieveRawBlock.of(Revision.BEST).askTo(
mockHttpClient<RawBlockResponseJSON>(
mockIncompleteRawBlock as RawBlockResponseJSON
mockHttpClient(
mockIncompleteRawBlock as RawBlockResponseJSON,
'get'
)
)
).rejects.toThrowError(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import { describe, test, expect } from '@jest/globals';
import { type FetchHttpClient } from '../../../src/http';
import {
RetrieveRegularBlock,
type RegularBlockResponseJSON,
RegularBlockResponse
} from '../../../src/thor/blocks';
import { Revision } from '@vechain/sdk-core';

const mockHttpClient = <T>(response: T): FetchHttpClient => {
return {
get: jest.fn().mockImplementation(() => {
return {
json: jest.fn().mockImplementation(() => {
return response;
})
};
})
} as unknown as FetchHttpClient;
};
import { mockHttpClient } from '../../utils/MockUnitTestClient';

/**
* VeChain regular block - unit
Expand Down Expand Up @@ -49,7 +37,7 @@ describe('RetrieveBlock unit tests', () => {

const mockRegularBlockResponse = await RetrieveRegularBlock.of(
Revision.BEST
).askTo(mockHttpClient<RegularBlockResponseJSON>(mockRegularBlock));
).askTo(mockHttpClient(mockRegularBlock, 'get'));
expect(mockRegularBlockResponse.response.toJSON()).toEqual(
new RegularBlockResponse(mockRegularBlock).toJSON()
);
Expand All @@ -63,8 +51,9 @@ describe('RetrieveBlock unit tests', () => {

await expect(
RetrieveRegularBlock.of(Revision.BEST).askTo(
mockHttpClient<RegularBlockResponseJSON>(
mockIncompleteRegularBlock as RegularBlockResponseJSON
mockHttpClient(
mockIncompleteRegularBlock as RegularBlockResponseJSON,
'get'
)
)
).rejects.toThrowError(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import { describe, test } from '@jest/globals';
import { QuerySmartContractEvents } from '../../../src/thor/logs/QuerySmartContractEvents';
import { type EventLogFilterRequestJSON } from '../../../src/thor/logs/EventLogFilterRequest';
import { type FetchHttpClient } from '../../../src';
import {
EventLogsResponse,
type EventLogsResponseJSON
} from '../../../src/thor/logs';

const mockHttpClient = <T>(response: T): FetchHttpClient => {
return {
post: jest.fn().mockImplementation(() => {
return {
json: jest.fn().mockImplementation(() => {
return response;
})
};
})
} as unknown as FetchHttpClient;
};
import { mockHttpClient } from '../../utils/MockUnitTestClient';

/**
*VeChain node - unit
Expand Down Expand Up @@ -66,7 +54,7 @@ describe('QuerySmartContractEvents unit tests', () => {
}
] satisfies EventLogsResponseJSON;

const mockClient = mockHttpClient<EventLogsResponseJSON>(mockResponse);
const mockClient = mockHttpClient(mockResponse, 'post');

const response =
await QuerySmartContractEvents.of(request).askTo(mockClient);
Expand Down Expand Up @@ -95,7 +83,7 @@ describe('QuerySmartContractEvents unit tests', () => {
order: 'asc'
};

const mockClient = mockHttpClient([]);
const mockClient = mockHttpClient([], 'post');

const response =
await QuerySmartContractEvents.of(request).askTo(mockClient);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
import { describe, test } from '@jest/globals';
import { QueryVETTransferEvents } from '../../../src/thor/logs/QueryVETTransferEvents';
import { type TransferLogFilterRequestJSON } from '../../../src/thor/logs/TransferLogFilterRequest';
import { type FetchHttpClient } from '../../../src';
import {
TransferLogsResponse,
type TransferLogsResponseJSON
} from '../../../src/thor/logs';

const mockHttpClient = <T>(response: T): FetchHttpClient => {
return {
post: jest.fn().mockImplementation(() => {
return {
json: jest.fn().mockImplementation(() => {
return response;
})
};
})
} as unknown as FetchHttpClient;
};
import { mockHttpClient } from '../../utils/MockUnitTestClient';

/**
*VeChain node - unit
Expand Down Expand Up @@ -66,8 +54,7 @@ describe('QueryVETTransferEvents unit tests', () => {
}
] satisfies TransferLogsResponseJSON;

const mockClient =
mockHttpClient<TransferLogsResponseJSON>(mockResponse);
const mockClient = mockHttpClient(mockResponse, 'post');

const response =
await QueryVETTransferEvents.of(request).askTo(mockClient);
Expand Down Expand Up @@ -97,7 +84,7 @@ describe('QueryVETTransferEvents unit tests', () => {
order: 'asc'
};

const mockClient = mockHttpClient([]);
const mockClient = mockHttpClient([], 'post');

const response =
await QueryVETTransferEvents.of(request).askTo(mockClient);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
import { describe, test } from '@jest/globals';
import {
type FetchHttpClient,
type PeerStatJSON,
RetrieveConnectedPeers
} from '../../../src';

const mockHttpClient = <T>(response: T): FetchHttpClient => {
return {
get: jest.fn().mockImplementation(() => {
return {
json: jest.fn().mockImplementation(() => {
return response;
})
};
})
} as unknown as FetchHttpClient;
};
import { type PeerStatJSON, RetrieveConnectedPeers } from '../../../src';
import { mockHttpClient } from '../../utils/MockUnitTestClient';

/**
*VeChain node - unit
Expand Down Expand Up @@ -45,15 +30,15 @@ describe('RetrieveConnectedPeers unit tests', () => {
inbound: true,
duration: 37
}
];
] satisfies PeerStatJSON[];

const mockPeersResponse = await new RetrieveConnectedPeers().askTo(
mockHttpClient<PeerStatJSON[]>(mockPeers)
mockHttpClient(mockPeers, 'get')
);
expect(mockPeersResponse.response.toJSON()).toEqual(mockPeers);

const emptyPeersResponse = await new RetrieveConnectedPeers().askTo(
mockHttpClient<PeerStatJSON[]>([])
mockHttpClient([], 'get')
);
expect(emptyPeersResponse.response.toJSON()).toEqual([]);
});
Expand Down
18 changes: 18 additions & 0 deletions packages/thorest/tests/utils/MockUnitTestClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { type HttpClient } from '../../src';

const mockHttpClient = <T>(
response: T,
httpMethod: 'get' | 'post'
): HttpClient => {
return {
[httpMethod]: jest.fn().mockImplementation(() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im bit lost why we need Jest involved here
dont we just implement HttpClient interface where the rest can pas in the beforeRequest and afterResponse functions themselves, and the mock doesnt actually do a http request?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

think of more of a Stub i guess

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied from my comment on Slack:
After thinking a bit about it, I'm not sure I see the problem with using HttpClient for mocking things. We could be mock fetch and use FetchHttpClient with callbacks but that wouldn't change much about how it is testing things right now.
For the jest mock implementation fns those were needed for mocking FetchHttpClient but aren't needed now that it's using HttpClient, I have just removed them in the latest commit

return {
json: jest.fn().mockImplementation(() => {
return response satisfies T;
})
};
})
} as unknown as HttpClient;
};

export { mockHttpClient };
Loading