Authors unit tests for gRPC interceptor logic: Go grpc.UnaryServerInterceptor/UnaryClientInterceptor, Java ServerInterceptor/ClientInterceptor, and grpc-js client interceptors. Covers auth (Unauthenticated on bad token), retry (backoff on Unavailable), logging/tracing (metadata extraction + propagation), error-mapping (status translation), and chained interceptor ordering - by calling the interceptor directly with a spy handler, no live backend. Use when a gRPC interceptor is written or modified. Different test surface from grpc-streaming-test-author (multi-message stream sequences) and grpc-mock (service handler logic) - use those, not this, for streams or handlers.
74
93%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
@grpc/grpc-js exposes client interceptors as a channel option. The
package README confirms "Client Interceptors" as a supported feature at
github.com/grpc/grpc-node/tree/master/packages/grpc-js.
An interceptor is a function (options, nextCall) => InterceptingCall.
Test an auth-header injector by building an InterceptingCall with a
RequesterBuilder that captures the outbound metadata:
import * as grpc from "@grpc/grpc-js";
import { InterceptingCall, InterceptorOptions, NextCall } from "@grpc/grpc-js";
function authInterceptor(token: string) {
return (options: InterceptorOptions, nextCall: NextCall): InterceptingCall => {
return new InterceptingCall(nextCall(options), {
start(metadata, listener, next) {
metadata.add("authorization", `Bearer ${token}`);
next(metadata, listener);
},
});
};
}
// Test using a spy on the nextCall layer
test("authInterceptor injects Authorization header", () => {
let capturedMetadata: grpc.Metadata | undefined;
const fakeNext: NextCall = (_options) =>
new InterceptingCall(null as any, {
start(metadata, _listener, _next) {
capturedMetadata = metadata;
},
});
const interceptorFn = authInterceptor("my-token");
const call = interceptorFn({} as InterceptorOptions, fakeNext);
call.start(new grpc.Metadata(), {} as grpc.Listener);
expect(capturedMetadata?.get("authorization")).toEqual(["Bearer my-token"]);
});Register on a channel:
const client = new UserServiceClient(address, credentials, {
interceptors: [authInterceptor("my-token")],
});