gpt4 book ai didi

typescript - 如何在 jest/apollo 客户端中捕获被拒绝的 graphql 订阅?

转载 作者:行者123 更新时间:2023-12-02 20:22:02 26 4
gpt4 key购买 nike

我正在尝试使用 graphql-yoga 编写 Jest 测试来覆盖订阅。

我能够成功测试订阅有效(带有身份验证)的快乐路径。不幸的是,我无法测试订阅 websocket 连接被拒绝的情况。

在我的服务器设置中,我拒绝任何未通过我的身份验证标准的 Websocket 连接:

const app = await server.start({
cors,
port: process.env.NODE_ENV === "test" ? 0 : 4000,
subscriptions: {
path: "/",
onConnect: async (connectionParams: any) => {
const token = connectionParams.token;
if (!token) {
throw new AssertionError({ message: "NO TOKEN PRESENT" });
}
const decoded = parseToken(token, process.env.JWT_SECRET as string);
const user = await validateTokenVersion(decoded, redis);
if (user === {}) {
throw new AssertionError({ message: "NO VALID USER" });
}
return { user };
}
}
});

( https://github.com/jakelowen/typescript-graphql-boilerplate-server/blob/master/src/startServer.ts#L87 )

现在在我的相关测试中:https://github.com/jakelowen/typescript-graphql-boilerplate-server/blob/master/src/modules/counter/counter.test.ts

第一个测试(快乐的路径)如我所愿通过了:

// works as expected.
test("should start a subscription on network interface and unsubscribe", async done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);
await client.register(email, password);
await User.update({ email }, { confirmed: true });
await client.login(email, password);

// set up subscription listener
const sub = client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
done();
}
});
});

然后我尝试了 3 种不同的方法来满足我在未经身份验证的场景中看到的期望。这些测试都没有像我希望的那样通过:

// Does not work! I am expecting an error.
test("Unauthed subscriptions are rejected", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);

const sub = client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
done();
}
});

// Received value must be a function, but instead "object" was found
expect(sub).toThrow();
});

// does not work
// Error: Uncaught { message: 'NO TOKEN PRESENT' }
test("Unauthed subscriptions are rejected second attempt", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);

try {
const sub = client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
// done();
}
});
} catch (error) {
console.log(error);
expect(error).toEqual({
message: "NO TOKEN PRESENT"
});
done();
}
});

// does not work
// Error: Uncaught { message: 'NO TOKEN PRESENT' }
test("Unauthed subscriptions are rejected second attempt", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);

try {
const sub = client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
// done();
}
});
} catch (error) {
console.log(error);
expect(error).toEqual({
message: "NO TOKEN PRESENT"
});
done();
}
});

// does not work
// Expected the function to throw an error.
// But it didn't throw anything.
test("Unauthed subscriptions are rejected third attempt", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);

expect(async () => {
const sub = await client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
done();
}
});
}).toThrowError();
});

// does not work
// Expected the function to throw an error.
// But it didn't throw anything.
test("Unauthed subscriptions are rejected fourth attempt", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);

const attempt = async () => {
const sub = await client.client.subscribe(defaultOptions).subscribe({
next(result) {
expect(result).toEqual({
data: {
counter: {
count: 0
}
}
});
sub.unsubscribe();
done();
}
});
};

expect(attempt).toThrowError();
});

知道如何预期在未经身份验证的场景测试中出现我期望的断言错误吗?

完整的仓库:https://github.com/jakelowen/typescript-graphql-boilerplate-server

最佳答案

布亚。我一般性地阅读了 observables,特别是 observable.subscribe(),并发现第二个可选参数是 onError 回调函数。将测试重构为:

test("Unauthed subscriptions are rejected", done => {
const client = new TestClientApollo(process.env.TEST_HOST as string);
// jest.setTimeout(1000); // increase timeout
client.client.subscribe(defaultOptions).subscribe(
res => {
console.log(res);
},
err => {
expect(err).toEqual({ message: "NO TOKEN PRESENT" });
done();
}
);
});

一切都按预期进行。万岁!

旁白:令我惊讶的是,经过数十个小时的 google、stackoverflow 和 github 搜索,我从未找到关于如何正确测试 graphql 订阅的简单、清晰的教程。

关于typescript - 如何在 jest/apollo 客户端中捕获被拒绝的 graphql 订阅?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51140948/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com