-
-
Notifications
You must be signed in to change notification settings - Fork 104
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
Shared dispatcher/synchronization context with Renderer #739
Comments
Not sure if this is related to #687 or not, but I do believe the tests should wait for the render to complete. My ideal scenario would be to not have the "wait for" APIs at all, but instead, make each call only return once the handlers/rendering are complete. e.g.,
My understanding is that I can already call |
My thinking is that that should be the exception, not the rule. (i.e., what you have now). Not allowing the async-style testing forces the tests to handle scenarios that they are not interested in. (i.e., forcing the test author to figure out when to use "wait for" APIs, and when they need to use InvokeAsync().) Note, that I would imagine that even though the test doesn't continue until the render (the second render in your example) completes, the two renders still occur. (Catching, for example, exceptions caused by the 'loading...' not working.) |
@FlukeFan thanks for the input. The problem is that this will not work in all scenarios. Suppose you have a component that renders a "loading" text while it waits for an async service to return data in OnInitializeAsync. In that case, you might want to write a test that verifies that the loading text is displayed before the async service returns. So you pass a mock of the service to the component under test that returns an incomplete task, and that allows you to deterministically test that the loading content is shown correctly. However, if bUnit were to block until OnInitializeAsync completes, the test is essentially deadlocked. Another problem is that Blazor does not return an incomplete task if there is async code on OnAfterRenderAsync, it just allows the task to continue to run in the background. So a |
bUnit uses Blazor's renderer under the hood, and have to play by its rules. That means that any time an async method is hit during a render of a component, the render is reported as "completed" to the caller, and then the continuation of that async method is scheduled for a later render. So It maybe that the sync event handler trigger methods gets deprecated though, such that users will have to call e.g. We can avoid having to call The rule for when you would need to use the |
Ill close this as we already merged in a change where we use the users sync context to update rendered fragments after each render. |
Motivation:
Tests should be deterministic, and one of the biggest challenges with that is that the Renderer can asynchronous (re)render components while test code is being executed.
This can lead to subtle bugs, e.g. where a
cut.Find("button").Click()
results in the button being found and having a event handler attached whenFind
is executing, but whenClick
starts running, that event handler has changed. There are a lot of work arounds and safe guards in bUnit currently to make this as unlikely to happen, but there are probably still edge cases where users would have to wrap their test code in acut.InvokeAsync(() => ...)
call to ensure it runs without the renderer doing renders.There are still some things we need to figure out:
The text was updated successfully, but these errors were encountered: