-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Add draft for mock http client for unittesting #1980
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Thanks, @migueleliasweb . It is currently stuck on:
|
This is due to the differences in golang 1.16. I changed it to use the |
Now the error is:
|
For some reason this seems to be a flakey test 🤔 It passes most times but eventually fails. I'm troubleshooting.... |
The tests should pass now 🤞 . Ping @gmlewis 🔔 . |
Codecov Report
@@ Coverage Diff @@
## master #1980 +/- ##
==========================================
- Coverage 97.84% 97.43% -0.41%
==========================================
Files 105 106 +1
Lines 6809 6868 +59
==========================================
+ Hits 6662 6692 +30
- Misses 80 108 +28
- Partials 67 68 +1
Continue to review full report at Codecov.
|
OK, thanks, @migueleliasweb . I have some big concerns about this approach... especially from a maintenance perspective.
Before doing a full code review (where I would suggest that headers be added and |
Damn it, got Marshal wrong. I always spell it the wrong way. Second language problems, sry. Yeah,I'm afraid you're not wrong about the regexps. I was trying to come up with another way to match the requests but I ended up trying this one first. I thought of two other ways:
Ps: fixed the typo on |
I just wrote a poc with the runtime frames. The API looks much cleaner without the Have a look: https://github.com/migueleliasweb/go-github/blob/mock-transport-pc-frames/mock/client.go |
Ah, wow... that is quite intriguing, @migueleliasweb ! I'm guessing that the GitHub API call would be closer to the "recent" end of the call stack as opposed to the "oldest" end of the call stack... so it might make the most sense (from a performance perspective) to search for the call from the end to the beginning... actually maybe you are already doing that... if so, great. I'm not too concerned about the performance implications of the endpoint search... I think this would be much easier to support than the other solution... especially if the critical list of methods that users would use are auto-generated. Overall, I like this approach a lot... I think you are on to something big here! |
(just some random thoughts...) The use of caller frames to match the intercepted request is certainly an interesting approach, and one I probably wouldn't have considered. But I think it's a bit more rigid in tying the test to the method that made the http request, rather than what the request itself is. This is very close to being a really interesting, generic, standalone approach to intercepting and mocking outbound http requests. If that were the goal (to make this reusable beyond just go-github), then I wonder if the original URL matching approach might be more flexible. I also wonder if some of the regex logic could be made safer (or at least more maintainable) by using some of the path parsing and matching logic in something like gorillatoolkit (or similar framework)? That could allow writing paths to match using a friendlier syntax like |
The problem as @gmlewis already pointed out, there's not (as far as I know) way to determine which call was made in the current state of the codebase. Using the regexps could end up being a bit tedious to handcraft all the required expressions and ensure they don't collide to each other. The workaround was the
Using something like the gorillamux would definitely make the request matching much more friendly but I thought this repo in general was trying to not bring more remote dependencies. And also, once again, maintaining all the paths, although it would be much easier with the gorilla mux or something similar, would still mean all those paths would have to be handcrafted and maintained for the future. Thanks for the feedbackm @willnorris ! 👍 |
I will try to add the code generation to the |
Closing in favor of #2008 |
We're primarily talking about using this technique to test application code that is calling into go-github. Ideally, you'd be testing discrete functionality, so I'd be surprised if there were that many overlapping API calls in a given unit test. And I'm not sure that the Frames approach necessarily solves that problem anyway, but rather moves it. You could still have multiple outbound calls that are originating from the same function, so you've still got overlapping calls. Regardless of the approach (URL matching or frame matching), I don't think this belongs in go-github. We're talking about rather generic approaches to intercepting output calls, which could make a very interesting standalone library, similar to https://github.com/nock/nock in Node. In fact, I think Nock provides a good example of doing this with URL matching and might provide a pretty well-tested API to potentially model (if you wanted to take that approach) Even if this were not fully generic, and is instead specific to go-github, this is only intended for use by users of go-github. It's not used by the library itself. So I think this should really be its own repo, which we can optionally link to from go-github's README as one approach to testing applications that use the library. (/cc @gmlewis) |
It is true that this code is more like a helper other than something integral to this repo so I see no big problem of moving this logic to a new repo. Something like Where would this new repo reside? If inside Also, if we're decided to move this PR to a new repo, @willnorris idea of using like |
I see no reason why it couldn't be under your own user name, but we'll see what @willnorris says. |
yeah, I was imagining just under your own account, at least to start out. I don't think it will ever make sense to put it under @google, since no one from Google is actively involved with this at this point. |
Hi @willnorris and @gmlewis I think I have something that is somewhat presentable. Let me know if, other than the missing CI, there's something else I'm missing. https://github.com/migueleliasweb/go-github-mock ps: don't know where to have this conversation, if you guys prefer to create issues in the repo itself, feel free |
Sounds great, @migueleliasweb ! Thanks for doing that! Feel free to create a PR to add a reference to your new repo in this repo's README.md so we can point people to it. |
Will do, @gmlewis . I just wanted a couple more hours to ensure the tests are being run in the CI workflow before opening the floodgates 😂 . |
No description provided.