Skip to content

Include test name that is causing Bunit.JSRuntimeUnhandledInvocationException #521

Closed

Description

@anddrzejb

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?

Activity

  1. egil commented on Oct 19, 2021

    @egil
    Member

    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.

  2. anddrzejb commented on Oct 19, 2021

    @anddrzejb
    ContributorAuthor

    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.

  3. egil commented on Oct 20, 2021

    @egil
    Member

    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).

  4. anddrzejb commented on Oct 20, 2021

    @anddrzejb
    ContributorAuthor

    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.

  5. egil commented on Oct 20, 2021

    @egil
    Member

    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.

  6. anddrzejb commented on Oct 20, 2021

    @anddrzejb
    ContributorAuthor

    All suggestions are fine with but with cons:

    • 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 💯 🙇🏻‍♂️ .

  7. egil commented on Oct 20, 2021

    @egil
    Member

    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.

  8. anddrzejb commented on Oct 20, 2021

    @anddrzejb
    ContributorAuthor

    I have had similar challenges with bUnit from time to time, and created the following test-runner script

    That is a nice idea, thanks for sharing!

  9. egil commented on Oct 20, 2021

    @egil
    Member

    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

  10. anddrzejb commented on Oct 20, 2021

    @anddrzejb
    ContributorAuthor

    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.

  11. egil commented on Oct 20, 2021

    @egil
    Member

    All suggestions are fine with but with cons:

    • 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.

  12. locked and limited conversation to collaborators on Oct 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions