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
Message from Assertk assertions is not printed when using withArg block. #707
Comments
Any updates on this? It's a REALLY nice feature, but without logging the exception (in my case from Google Truth), it makes it very un-maintainable when the matcher fails |
I'll get a PR up for this. I think it's pretty easy (just a log statement inside the catch of the matcher)
|
Yep that seems like the right place to log the error message, thanks for looking into it! |
@Raibaz (assuming you’re a maintainer) How do you guys do logging? I can obviously add a println, but I’m guessing you have some sort of standard? Do I need to inject a logged somehow? |
Oof. Looks like I can't even run the project (I'm on a work machine and they have VPN constraints that don't allow me to download project dependencies. I'll put up a PR with the println - but I'm guessing someone will want to go in and change it to some sort of logger before merging |
I believe I gave access for maintainers to push directly to my fork. Feel free to have at it if you know how to do the logging @Raibaz :) |
First of all, thanks a lot for looking into this. On second thought, though, I see an issue with your test implementation: argument matchers are meant just for matching arguments, not to perform any logic, or assertions, on the arguments themselves. What you are actually doing in your test is definitely better achieved by capturing the argument and then performing assertions on it, something like:
Note that by using a slot, you can also log the argument values if needed, or perform any other sorts of logic onto it. A matcher is definitely not the right place to perform assertions; perhaps we should document this better. Also, if you check issue #389, which was the reason why the catch block was added, I was mentioning the same thing about capturing the argument being a better way of achieving the same result :) Thinking again about it, I don't think catching |
Ah bummer. I get your point, but it sure was nice to be able to run assertions as part of the verification... (e.g. verify that the function was called with an argument that matches these assertions, rather than verify the method was called with anything, followed by assertions). So is your only concern the fact that this is muddying the waters for the matcher? Is there any way to rearchitect this so that it only applies to the withArg function? It seems that there are a number of articles out there recommending for people to use withArg to run assertions (not that we’re supposed to cater to them, but to show that users do like using the withArg to avoid the slot approach): |
It's not just a matter of muddying waters, it's really that matchers are meant for matching parameters, not to execute code, and thus they live in a module where there is neither logging enabled or actually any other dependencies. Adding a logging dependency just for this case seems really overkill to me, given that there is a better, clearer way to achieve the same behavior. |
@Raibaz so then what's supposed to be the difference between Don't get me wrong, I completely understand the hesitation to add a logger if it's not needed - but from a consumer point of view, I think that being able to run assertions as part of the verification is way more developer-friendly than having to capture a slot and run separate assertions
vs
You can see how the the Just food for thought. It just seems like a major win from a library perspective that would be sad to lose simply because a logger wasn't injected into the right place |
I totally agree with your point about This being said, I looked back at #389, which was the issue that made me introduce the specific catch for the AssertionError, and I am wondering: in that case, the same function is being verified twice with different arguments. This means that the assertion logic is being used to drive the matching logic too: if all assertions on the arguments pass, then the argument is matching, otherwise it's not, and that is the way MockK matches the two different calls and passes the test. The case when a user wants to verify two different calls to the same method in the same I don't have any usage details on this, but it seems to me I fixed a less-common use case and broke a more common one :( What do you think? |
(also, thanks for taking the time to investigate this and for the suggestions!) |
Of course :) Thanks for listening. Yeah, if we remove the try/catch and the errors bubble up, that definitely solves the use case that this issue is specifically addressing. If you feel comfortable with that fix, I'll modify my PR to do that instead Once again, I can't run the test suite locally, but feel free to push anything to my branch if you know of any other changes that would need to be made to support this However, I'm not familiar with the original issue - so if you think we still need to rethink things, let me know |
Yep your PR was perfectly fine, thanks a lot! This issue can be closed then. |
Thanks! So how do release cycles work? Is every PR merged to master a new version of mockk? If so, where would I find the new build version? Or do you cut releases on a cadence? |
I usually do releases manually once there are enough new changes. I already did some changes to add support for Kotlin 1.6.* and remove support for 1.3.*, so I may actually make a release pretty soon. |
Meanwhile, you can obviously build your own snapshot from master :) |
We may need to revert this change. One unintended consequence is that in cases when multiple calls are made to the same mock, this will fail when matching the first one... Test that succeeded before 12.3.1:
now fails... |
I didn't realize that the Matcher was being run for each call, and having an exception thrown would fail it immediately. I thought that the exception would get bubbled up, and that the matcher would move on to the next one - only printing the exception if the full matcher failed. I probably should have looked at #389 a little closer before submitting the PR :( |
So @Raibaz we're kinda back at square one... 😂 The original "Add a logger" solution would be slightly better, but would give false positives (it would log failures, even if it will eventually find a call that succeeds). The best solution that I can imagine (from a naive perspective) is kinda what you're already doing with verify (where it shows all the calls that were made, and what didn't match), but ALSO print the assertion error at that point for each call. So that way, the assertion error is only printed when the overall verification fails, but it still allows it to check through all calls. So it would look kinda like this:
Thoughts? I'm not sure how difficult that would be to implement... Essentially, capturing the assertion errors and adding them to the resulting failure |
Is there any update on this? Or is the only way to make it work to use a capture? Having no messages is especially cumbersome when using recursive AssertJ statements inside a |
One workaround with slot() for common situations that is a little more concise and also scoped is the following:
|
Prerequisites
Please answer the following questions for yourself before submitting an issue.
Expected Behavior
The message from AssertionFailedError (which is thrown by Assertk lib) should be printed when assertion is performed in withArg block.
Current Behavior
The message from AssertionFailedError (which is thrown by Assertk lib) exception is not printed when the checking is performed in withArg block.
Context
Please provide any relevant information about your setup. This is important in case the issue is not reproducible except for under certain conditions.
Minimal reproducible code (the gist of this issue)
I found that exception is catched here, and the stacktrace is not logged.
The text was updated successfully, but these errors were encountered: