visit
export const commonHeaders = {
[AUTHORIZATION_HEADER]: AUTH_HEADER,
'Content-Type': 'application/json',
};
export function createSuperTestRequest(useExternalToken = false): SuperAgentTest {
const request = agent(PlatformTest.callback());
request.set(commonHeaders);
if (useExternalToken) {
request.set(EXTERNAL_TOKEN_HEADER, EXTERNAL_TOKEN);
}
return request;
}
The createSuperTestRequest
function has a useExternalToken
parameter, but it can be something more complex like an options = { useExternalToken: false, cookies: {…}}
object. So, that approach allows you to create some complex ‘request’ in one place.
Next, it would be great to have all requests related to the specific controller in one class. It helps to reuse the same endpoint request between multiple tests. And each method can be specified with additional data like timeout(2000)
.
export class UserApiClient {
constructor(private readonly request: SuperTest<Test>) {}
async create(name: string): Promise<Response> {
const data = name === '' ? {} : { name };
return this.request.post(USER_URL).timeout(2000).send(data);
}
...
}
In some endpoints, you will use Query parameters; you can put such parameters inside the request string. However, there is a specific function query()
. It works like HashSet as well as set()
function for headers.
public get(userId: number, includeCounters = false) {
return this.request
.get(USER_URL)
.query({ includeCounters: includeCounters });
}
describe('Your API tests', () => {
let userApiClient: UserApiClient;
before(PlatformTest.bootstrap(Server));
before(() => {
const request = createSuperTestRequest();
apiClient = new UserApiClient(request);
});
...
}
sinon.stub(RulesClient.prototype, 'send').resolves({
rules
});
Also, this approach can stub the private function in the class. The private
modifier usually adds more complexity for the testing, but not so much when you are using JS and Sinon.
export class RulesClient {
public send(rule: Rule): Promise<RuleResult> {
this.checkUser();
return ...;
}
private checkUser() {
...
}
}
This private function checkUser()
can be mocked by sinon as well. Use casting to type any, like 'checkUser' as any
or like <any> 'checkUser'
.
sinon.stub(RulesClient.prototype, 'checkUser' as any).callsFake(() => {})
afterEach(async () => {
sinon.restore();
});
Photo by on