Closed uynap closed 4 years ago
My understanding of this situation is as follows:
(a) there is hand-written code to handle the PostFoo endpoint
(b) PostFoo endpoint needs to call PostBarr on some downstream system
(c) the hand-written PostFoo handler code needs to access the raw common.RestResult (e.g. to get the raw HTTP status code), instead of using the type returned by the generated client code.
(d) we want to unit test the hand-written PostFoo handler code by mocking the PostFooClient
's PostBarr
method.
E.g. the situation might look something like:
// hand-written code to handle the PostFoo endpoint:
func (h *Handler) PostFoo(ctx context.Context, req *app.PostFooRequest, client app.PostFooClient) (*app.PostFooResponse, error) {
ctx = common.ProvisionRestResult(h.ctx) // step [1]
request := ...etc... // build PostBarrRequest to send to downstream Barr system
response, err := client.PostBarr(h.ctx, &request)
if err != nil {
return nil, err
}
responseHeader := common.GetRestResult(h.ctx) // step [3]
switch (responseHeader.StatusCode) { // step [4]
case http.StatusCreated:
return something, nil
case http.StatusAccepted:
return somethingElse, nil
}
return nil, errors.New("unexpected response from some other service")
}
// generated code, inside generated client for PostBarr operation of the downstream Barr system
func (s *Client) PostBarr(ctx context.Context, req *PostBarrRequest) (*PostBarrResponse, error) {
// ...etc...
result, err := restlib.DoHTTPRequest(...etc...)
restlib.OnRestResultHTTPResult(ctx, result, err) // step [2]
// ...etc...
}
my understanding is that it is possible to unit test PostFoo
by mocking (s *Client) PostBarr(ctx context.Context, req *PostBarrRequest) (*PostBarrResponse, error)
-- the mock of (s *Client) PostBarr(ctx context.Context, req *PostBarrRequest) (*PostBarrResponse, error)
can call restlib.OnRestResultHTTPResult(ctx, result, err)
, but it needs to do it after step [1] but before step [3].
Thanks @anz-rfc . The restlib.SetRestResult
makes everything working. Thanks for the help.
Accessing the downstream HTTP response code is supported in current Sysl generated code, but it's hard to have unit testing.
Current way: In the BFF endpoint that you want to access the downstream HTTP response code, firstly call
ctx = common.ProvisionRestResult(ctx)
Then, make the downstream call. Followed by using thecommon.GetRestResult(ctx)
to retrieve the response information.The problem is I can't mock the downstream response because the
ProvisionRestResult
method always reset the response inside of the handler.Suggested approaches
I think the most easier solution is adding the
ctx = common.ProvisionRestResult(ctx)
to the endpoint's wrapper in the bff/servicehandler.go. It's a kind of initiating a context key and it's not a breaking change to others.