![](/img/trans.png)
[英]How do you map PubSub value of a GraphQL subscription in Apollo?
[英]How to catch rejected graphql subscription in jest / apollo client?
我正在嘗試使用graphql-yoga編寫玩笑測試來涵蓋訂閱。
我能夠成功地測試訂閱模式(使用auth)的快樂路徑。 不幸的是,我無法測試預訂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/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,堆棧溢出和github搜索,我從未發現一個有關如何正確測試graphql訂閱的簡單明了的教程,這讓我感到驚訝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.