Hello,
I have code that uses httpclient. I would like to write test with a mocked httpclient, so that I can focus on testing the logic of my code.
I'm new to Nim and can't figure out how to do that (e.g. google "nim unit test mock" didn't yield anything)
Any example would be great.
Thank you.
Unfortunately I'm not aware of any mock unit testing libraries in Nim, so it seems that you might have to implement one if you want to use it.
As for how to do that... I'd say you would have to delve into macros.
You can use a custom httpclient implementation via a project.nims config file and the usage of patchFile:
https://nim-lang.org/docs/nimscript.html#patchFile,string,string,string
Personally I never use mocking, I need the "integration" tests anyway and they subsume the "mocking" tests.
What Araq suggested answers my next question, "what is a good way to write test?". Swapping out implementation using patchFile is probably okay.
My use case is a command-line tool (deployed to different OSes) with a lot of business logic, so great unit testing is important.
Efficiency isn't a concern, while expressiveness and elegance are important. (For me, that's where Nim wins over Golang/Rust. Thanks for creating the language, Araq).
I'd still prefer defining the behaviour of an external dependency within a test itself (for readability). I'll try patchFile, and, if not satisfied, I'll try to use macro to build a mock library. Thank you both for the suggestions.
As the author of said lib I would like to very, very heavily emphasize: The tooling provided there does not work on generics or anything other than explicit procs/funcs
The reason for that being that generic procs are not actual procs, but a kind of template in a sense that gets copy-pasted around by the compiler. So the simple idea of "turn a generic proc declaration into a mutable variable assignment" doesn't quite pan out. I have been told that it should be possible by Elegantbeef and others, but honestly I've come to the conclusion that I have nowhere near the competence in macros and similar to solve this, so I'll have to leave this one up to contributions to develop further tooling.
Anyway, what I actually wanted was to reply to the article: I agree with the assessment of the problem, that mocking frameworks lead to people testing side-effects where they really, really shouldn't. The very large problem is, and that is one that I see loads of articles fail to elaborate on, that how the alternative is supposed to look like in practice is a completely nebulous concept to me.
With Mocking Frameworks I can make sure that I cover all situations this piece of code may face. I can be a lot more complete. Without them I'm left with integration testing for proc A from start to finish, even if it calls proc B, which calls proc C, which calls D, which calls E, which calls F. It is a lot more effort to make sure you cover all code-paths here via tests, so most likely you'll end up sacrificing completeness.
What is the alternative to this? Design your code so that your call-hierarchy remains as flat as possible, leaving you with one large main proc whose individual side-procs are the ones whose behaviour actually gets tested?
I've been keeping an eye around this topic in chat for ages and keep chatting up people around this, the answers by and large are basically to give up on unit-testing and the desire to want to ensure the behaviour of your code for all situations and stick with integration testing, golden-testing or decide on some level near the top of your call-hierarchy whose procs actually get covered with unit-tests and the rest is only tested as part of their tests. I'm not fully satisfied with any of those answers, thus my attempt with mockingbird, though I'm not seeing any path forward without being able to cover generics as well.