如何在没有自定义拦截器的测试中设置上下文

时间:2019-05-07 08:30:45

标签: java grpc grpc-java

我尝试编写RouteGuideServerTest.java中所示的单元测试。事实是,我的服务从Context.Key<UserContext>中设置的UserContextInterceptor中读取了一些用户上下文信息(例如userID,ip等)。 问题是我不想在JUnit测试代码中同样创建拦截器,也不想在测试方法中手动设置Context,但是找不到正确的方法。

我在Context.Key<UserContext> USER_CONTEXT中有一些Constant.java,并尝试以另一种方式设置上下文:

Context.current().withValue(Constant.USER_CONTEXT, userContext).run(() -> { // some testing code })

,但是当 run 发生在与调用者线程不同的线程中时,从Constant.USER_CONTEXT.get()返回的上下文在服务代码中始终为null

Constant.java

public static final Context.Key<UserContext> USER_CONTEXT = Context.key("userContext");

GrpcService.java


@Override
    public StreamObserver<EntityRequest> process(StreamObserver<EntityResponse> responseObserver) {
        return new StreamObserver<EntityRequest>() {

            @Override
            public void onNext(EntityRequest request) {
                Constant.USER_CONTEXT.get(); // is always null in tests
            }
            // other methods
        };
}

GrpcServiceTest.java

@Test
public void test() {
    UserContext mockedContext = ...; // set user context 
    Context.current().withValue(Constant.USER_CONTEXT, mockedContext)
        .run(() -> {
            // testing code, call service rpc method  
        });
}

在没有拦截器的测试中设置Context以便在GrpcService中使用其模拟值且不包含null的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

该问题与用于执行哪个线程无关。 Context.run()在当前线程中运行。并且RouteGuideServerTest已经使用serverBuilder.directExecutor()来使服务在测试线程中运行。

问题是服务器具有自己的根Context,用于入站RPC,与调用时恰好在当前线程上的Context不同。这需要拦截器进行更改。