调用test函数时无法使用grpc.SetHeader或grpc.SendHeader设置标头。

huangapple go评论107阅读模式
英文:

Not able to set header when calling test function with grpc.SetHeader or grpc.SendHeader

问题

我有一个函数,可以将一些内容添加到gRPC头部中。

func Dummy(ctx context.Context, request *service.Request) error {
  err := grpc.SetHeader(ctx, metadata.Pairs("key", "value"))
  return err
}

当使用service调用它时,它可以正常工作。

但是,在为此编写单元测试用例时,它总是失败并显示以下错误:

rpc error: code = Internal desc = grpc: failed to fetch the stream from the context context.TODO

func TestDummy() {
 ctx := context.TODO()
 err := Dummy(ctx, &service.Request{})
}

我知道我可以模拟grpc.SetHeader,但我不想这样做。是否有其他方法可以解决这个问题?

英文:

I have a function which add something into the grpc header

func Dummy(ctx context.Context, request *service.Request) error {
  err := grpc.SetHeader(ctx, metadata.Pairs("key", "value"))
  return err
}

This works fine when it gets called with service.

While writing the unit test case for this, it always fails with:

> rpc error: code = Internal desc = grpc: failed to fetch the stream from the context context.TODO

func TestDummy() {
 ctx := context.TODO()
 err := Dummy(ctx, &service.Request{})
}

I know I can mock grpc.SetHeader, but I don't want to do that. Is there any other way we can fix this?

答案1

得分: 1

错误发生是因为context.TODO()中没有服务器流实现。您可以使用grpc.NewContextWithServerTransportStream替代context.TODO()

但是,您仍然需要模拟ServerTransportStream接口,但这并不过于复杂。实际上,该接口的目的正是允许测试使用grpc.SetHeader的代码。

骨架代码:

type mockServerTransportStream struct {}

func (m *mockServerTransportStream) Method() string {
	return "foo"
}

func (m *mockServerTransportStream) SetHeader(md metadata.MD) error {
	return nil
}

func (m *mockServerTransportStream) SendHeader(md metadata.MD) error {
	return nil
}

func (m *mockServerTransportStream) SetTrailer(md metadata.MD) error {
	return nil
}

func TestDummy() {
	ctx := grpc.NewContextWithServerTransportStream(&mockServerTransportStream{})
	err := Dummy(ctx, &service.Request{})
}

请注意,这只是一个示例代码,您需要根据您的实际情况进行适当的修改。

英文:

The error happens because there isn't a server stream implementation inside context.TODO(). Instead of context.TODO() you can use grpc.NewContextWithServerTransportStream.

You still need to mock the ServerTransportStream interface though, but that's not excessively complicated. In fact, the purpose of this interface is exactly to allow testing code that uses grpc.SetHeader.

Skeleton code:

type mockServerTransportStream struct {}

func (m *mockServerTransportStream) Method() string {
	return "foo"
}

func (m *mockServerTransportStream) SetHeader(md metadata.MD) error {
	return nil
}

func (m *mockServerTransportStream) SendHeader(md metadata.MD) error {
	return nil
}

func (m *mockServerTransportStream) SetTrailer(md metadata.MD) error {
	return nil
}

func TestDummy() {
 ctx := grpc.NewContextWithServerTransportStream(&mockServerTransportStream{})
 err := Dummy(ctx, &service.Request{})
}

huangapple
  • 本文由 发表于 2022年11月10日 23:14:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/74391247.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定