You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Include test name that is causing Bunit.JSRuntimeUnhandledInvocationException #521
Is the feature request related to a problem? Please elaborate.
I develop in Visual Studio. I often am in a situation that my local tests are passing, but in github actions I get an exception like this:
Bunit.JSRuntimeUnhandledInvocationException: bUnit's JSInterop has not been configured to handle the call:
InvokeVoidAsync("AntDesign.interop.domManipulationHelper.scrollTo", Microsoft.AspNetCore.Components.ElementReference, Microsoft.AspNetCore.Components.ElementReference)
Configure bUnit's JSInterop to handle the call with following:
SetupVoid("AntDesign.interop.domManipulationHelper.scrollTo", Microsoft.AspNetCore.Components.ElementReference, Microsoft.AspNetCore.Components.ElementReference)
or the following, to match any arguments:
SetupVoid("AntDesign.interop.domManipulationHelper.scrollTo", _ => true)
The setup methods are available on an instance of the BunitJSInterop or
BunitJSModuleInterop type. The standard BunitJSInterop is available
through the TestContext.JSInterop property, and a BunitJSModuleInterop
instance is returned from calling SetupModule on a BunitJSInterop instance.
at Bunit.BunitJSInterop.TryHandlePlannedInvocation[TValue](JSRuntimeInvocation invocation) in /_/src/bunit.web/JSInterop/BunitJSInterop.cs:line 84
at Bunit.BunitJSInterop.HandleInvocation[TValue](JSRuntimeInvocation invocation) in /_/src/bunit.web/JSInterop/BunitJSInterop.cs:line 69
at Bunit.JSInterop.Implementation.JSRuntimeExtensions.HandleInvokeAsync[TValue](BunitJSInterop jSInterop, String identifier, Object[] args) in /_/src/bunit.web/JSInterop/Implementation/JSRuntimeExtensions.cs:line 14
at Bunit.JSInterop.BunitJSRuntime.InvokeAsync[TValue](String identifier, Object[] args) in /_/src/bunit.web/JSInterop/Implementation/BunitJSRuntime.cs:line 23
at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args)
at AntDesign.AntComponentBase.JsInvokeAsync(String code, Object[] args) in /home/runner/work/ant-design-blazor/ant-design-blazor/components/core/Base/AntComponentBase.cs:line
My problem is that I have no clue which test actually has this issue.
The suggested solution
Is it possible to add to the message the offending test name?
Hmm the stack trace should include it, but I might be able to throw the exception in a different way such that it does. That said, with the right output parameters for dotnet test you should be able to see what test was running when the exception was run.
Adding --verbosity normal includes every test with information if passed or not. Then I can see the exception popping between test starting & passed info (test is still marked as passed event if exception was thrown). This is a solution that works, however the log is spammed by plethora of useless information. If you think it is possible to improve the exception message, that would be great. If not, then just close this issue.
So you see an exception in the logs but no test is failing?
Sounds like you might need WaitForState or WaitForAssertion to make sure the component is actually done rendering before the test completes.
My guess is that the component continues to do is async renders after the test finishes.
Well, I tried that before, but the weird thing is in my local dev env I don't get this exception. Only during CI pipeline in github actions. And anyway the logging you suggest should happen on a test in question. But in the log I cannot figure out what test it is 😕 . So at this stage it is the --verbosity normal for me. Unless the repo maintainer rejects it, then the only hope is the exception message with test details.
Can you narrow it down to a few tests? What if you dont run tests in parallel but sequential, and look at tests that call AntDesign.AntComponentBase.JsInvokeAsync?
Another solution is to simply add a SetupVoid("AntDesign.interop.domManipulationHelper.scrollTo", _ => true) to a common test setup method that ensures that the JS invocation has been configured, then you dont get that exception.
sequential - slower execution; we are at 1000 tests, I expect to go to probably 10k at some point; I noticed the tests are much slower when doing codecov, I don't know how the speed would be affected with sequential.
register scrollTo for every test - I already do something similar in the test base class, but in that case it is a js call that is very often used; but then again is there any reason to be against registering all void js calls in the same manner? Except of course possibly performance impact?
I can easily find out which components use a particular js call, but not all tests that are testing those components are going to trigger the js call. Currently the component that spits out the exception has over 200 tests. I'd rather use the -v n option 😄.
If you think my request to add test name to the exception is unreasonable, I won't mind if you close this issue. I will continue to enjoy your great work 💯 🙇🏻♂️ .
Btw. the reason this happens on CI pipeline and not locally can be because you have a much faster machine, or that you are running a different OS.
I have had similar challenges with bUnit from time to time, and created the following test-runner script, it runs some or all tests in a loop until something breaks. Used that locally to run the tests until I could trigger the error locally and then be able to investigate faster.
Also, I am not sure I can provide more context in the stack trace in this scenario, where the invocation happens on a different thread than the test thread. In your case, the call is coming, perhaps after a Task.Delay or similar, from AntDesign.AntComponentBase.JsInvokeAsync and ends up causing an exception to be thrown here: https://github.com/bUnit-dev/bUnit/blob/main/src/bunit.web/JSInterop/BunitJSInterop.cs#L86
One thing I noticed - when I was debugging to try to figure out what was the problem with #522 (so I had bUnit as a referenced project, not a nuget), I noticed that a lot of my tests were getting this exception (but complaining about different js calls). I guess this is probably because debug is much slower and the call was actually executed (thus causing the exception) in opposition to just running the tests.
sequential - slower execution; we are at 1000 tests, I expect to go to probably 10k at some point; I noticed the tests are much slower when doing codecov, I don't know how the speed would be affected with sequential.
codecov slows things down. however, running locally sequentially should work, and you can filter out tests that you know are not affected to e.g. only run a few. See my test runner script linked above
register scrollTo for every test - I already do something similar in the test base class, but in that case it is a js call that is very often used; but then again is there any reason to be against registering all void js calls in the same manner? Except of course possibly performance impact?
There is no performance difference, or nothing measurable. It might actually be faster if it is registered. However, for tests where you specifically want to do something with the invocation handler that you get when you setup an invocation.
I can easily find out which components use a particular js call, but not all tests that are testing those components are going to trigger the js call. Currently the component that spits out the exception has over 200 tests. I'd rather use the -v n option 😄.
I get that. You can always just ignore the error by registering an invocation handler or changing the JSInterop.Mode to Loose. Setting it to loose in a common base-test class allows you to change it to strict for the specific tests where you want it. With Loose, you dont have to register any handlers.
If you think my request to add test name to the exception is unreasonable, I won't mind if you close this issue. I will continue to enjoy your great work 💯 🙇🏻♂️ .
I wont say unreasonable, probably more impossible :) Thanks, and lets convert this to an discussion. Would love to know if you end up figuring out under what condition this happens in, maybe there is something I can then.
Activity
egil commentedon Oct 19, 2021
Hmm the stack trace should include it, but I might be able to throw the exception in a different way such that it does. That said, with the right output parameters for
dotnet testyou should be able to see what test was running when the exception was run.anddrzejb commentedon Oct 19, 2021
Adding
--verbosity normalincludes every test with information if passed or not. Then I can see the exception popping between test starting & passed info (test is still marked as passed event if exception was thrown). This is a solution that works, however the log is spammed by plethora of useless information. If you think it is possible to improve the exception message, that would be great. If not, then just close this issue.egil commentedon Oct 20, 2021
Ahh the test passes?
So you see an exception in the logs but no test is failing?
Sounds like you might need WaitForState or WaitForAssertion to make sure the component is actually done rendering before the test completes.
My guess is that the component continues to do is async renders after the test finishes.
Try adding logging to better see what's going on (https://bunit.dev/docs/misc-test-tips.html#capturing-logs-from-ilogger-in-test-output).
anddrzejb commentedon Oct 20, 2021
Well, I tried that before, but the weird thing is in my local dev env I don't get this exception. Only during CI pipeline in github actions. And anyway the logging you suggest should happen on a test in question. But in the log I cannot figure out what test it is 😕 . So at this stage it is the
--verbosity normalfor me. Unless the repo maintainer rejects it, then the only hope is the exception message with test details.egil commentedon Oct 20, 2021
Can you narrow it down to a few tests? What if you dont run tests in parallel but sequential, and look at tests that call
AntDesign.AntComponentBase.JsInvokeAsync?Another solution is to simply add a
SetupVoid("AntDesign.interop.domManipulationHelper.scrollTo", _ => true)to a common test setup method that ensures that the JS invocation has been configured, then you dont get that exception.anddrzejb commentedon Oct 20, 2021
All suggestions are fine with but with cons:
scrollTofor every test - I already do something similar in the test base class, but in that case it is a js call that is very often used; but then again is there any reason to be against registering all void js calls in the same manner? Except of course possibly performance impact?-v noption 😄.If you think my request to add test name to the exception is unreasonable, I won't mind if you close this issue. I will continue to enjoy your great work 💯 🙇🏻♂️ .
egil commentedon Oct 20, 2021
Btw. the reason this happens on CI pipeline and not locally can be because you have a much faster machine, or that you are running a different OS.
I have had similar challenges with bUnit from time to time, and created the following test-runner script, it runs some or all tests in a loop until something breaks. Used that locally to run the tests until I could trigger the error locally and then be able to investigate faster.
anddrzejb commentedon Oct 20, 2021
That is a nice idea, thanks for sharing!
egil commentedon Oct 20, 2021
Also, I am not sure I can provide more context in the stack trace in this scenario, where the invocation happens on a different thread than the test thread. In your case, the call is coming, perhaps after a
Task.Delayor similar, fromAntDesign.AntComponentBase.JsInvokeAsyncand ends up causing an exception to be thrown here: https://github.com/bUnit-dev/bUnit/blob/main/src/bunit.web/JSInterop/BunitJSInterop.cs#L86anddrzejb commentedon Oct 20, 2021
One thing I noticed - when I was debugging to try to figure out what was the problem with #522 (so I had
bUnitas a referenced project, not a nuget), I noticed that a lot of my tests were getting this exception (but complaining about different js calls). I guess this is probably because debug is much slower and the call was actually executed (thus causing the exception) in opposition to just running the tests.egil commentedon Oct 20, 2021
codecov slows things down. however, running locally sequentially should work, and you can filter out tests that you know are not affected to e.g. only run a few. See my test runner script linked above
There is no performance difference, or nothing measurable. It might actually be faster if it is registered. However, for tests where you specifically want to do something with the invocation handler that you get when you setup an invocation.
I get that. You can always just ignore the error by registering an invocation handler or changing the JSInterop.Mode to
Loose. Setting it to loose in a common base-test class allows you to change it to strict for the specific tests where you want it. WithLoose, you dont have to register any handlers.I wont say unreasonable, probably more impossible :) Thanks, and lets convert this to an discussion. Would love to know if you end up figuring out under what condition this happens in, maybe there is something I can then.