Simple example for bunit source generator #1358
Replies: 3 comments
-
Hey @ignatandrei - interesting list! Really nice initiative and having I am not sure if this helps you a lot, but here are all the tests for said generator: https://github.com/bUnit-dev/bUnit/tree/main/tests/bunit.generators.tests/Web.Stub The components that are "stubbed" by the generator are under the "Components" folder in the same directory. Let us know if this is good enough, otherwise we can also craft maybe a better example (closer to the real world and more expressive). |
Beta Was this translation helpful? Give feedback.
-
Thanks , I will look into Web.Stub . However, if you find a better example, closer to the programmers, it will be really helpfull . |
Beta Was this translation helpful? Give feedback.
-
Okay let's start with a bit of context as I am not 100% sure of how much context you have. Imagine you have 3rd party component that rely heavily on JavaScript Interop and or do need extensive setup to trigger certain situtations. A good example might be something like the QuickGrid. It utilizes JavaScript - that you have to take care of it. A way to deal with that is to use Stubs or Fakes. Kind of like shallow rendering if you want. That is where the generators try to help you. They generate a stub for you that you can use in your tests. The stubs are generated based on the component you supply. There are two ways to achieve that: Via an attribute and via the new .NET 8 feature: Interceptors. Let's make the attribute example here. Given a @implements IAsyncDisposable
<button @onclick="StartTimer">Start Timer</button>
<button @onclick="StopTimer">Stop Timer</button>
@code {
[Parameter] public int Interval { get; set; } = 1000; // 1 second
[Parameter] public EventCallback OnMinutePassed { get; set; }
[Inject] private IJSRuntime JSRuntime { get; set; }
private IJSObjectReference _module;
private int _elapsedTime = 0;
protected override async Task OnInitializedAsync()
{
_module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./timer.js");
}
private async Task StartTimer()
{
_elapsedTime = 0;
await _module.InvokeVoidAsync("startTimer", DotNetObjectReference.Create(this), Interval);
}
private async Task StopTimer()
{
await _module.InvokeVoidAsync("stopTimer");
}
[JSInvokable]
private async Task UpdateTimer()
{
_elapsedTime += Interval;
if (_elapsedTime >= 60000)
{
if (OnMinutePassed.HasDelegate)
{
await OnMinutePassed.InvokeAsync(null);
}
_elapsedTime = 0; // Reset the timer
}
}
public async ValueTask DisposeAsync()
{
if (_module != null)
{
await _module.InvokeVoidAsync("stopTimer");
await _module.DisposeAsync();
}
}
} Now there are two obstacles here:
Here is where the generators comes into play: [ComponentStub<TimerComponent>]
public partial class TimerComponentStub
{
public void RaiseEvent() => OnMinutePassed.InvokeAsync();
} This will automatically have all public parameters defined and we can write slim helper methods like [Fact]
public void Timer_component_gets_initial_timer_value()
{
ComponentFactories.AddStub<TimerComponent>();
var cut = RenderComponent<ParentComponent>();
var stub = cut.FindComponent<TimerComponentStub>();
stub.Instance.Interval.ShouldBe(1000);
}
[Fact]
public void When_one_minute_passed_state_is_changed()
{
ComponentFactories.AddStub<TimerComponent>();
var cut = RenderComponent<ParentComponent>();
var stub = cut.FindComponent<TimerComponentStub>();
stub.Instance.RaiseEvent();
cut.Find(".saved").TextContent.ShouldBe("Saved");
} Hope that is somewhat better. |
Beta Was this translation helpful? Give feedback.
-
Hello
I maintain an opinionated list of Roslyn Code Generators at https://ignatandrei.github.io/RSCG_Examples/v2/docs/List-of-RSCG
I want to add yours .
Could you indicate in this repo a simple example of bunit generators ?
( I have checked ThirdPartyText , but I do not find any source code example to inspire me)
Beta Was this translation helpful? Give feedback.
All reactions