bunit-test-migration
Updates legacy bUnit test code to the 2.x stable API. Fixes deprecated test patterns in Blazor component tests.
Install
mkdir -p .claude/skills/bunit-test-migration && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2856" && unzip -o skill.zip -d .claude/skills/bunit-test-migration && rm skill.zipInstalls to .claude/skills/bunit-test-migration
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Migrate bUnit test files from deprecated beta API (1.0.0-beta-10) to bUnit 2.x stable API. Use this when working on .razor test files in BlazorWebFormsComponents.Test that contain old patterns like TestComponentBase, Fixture, or SnapshotTest.Key capabilities
- →Migrate test inheritance to BunitContext
- →Convert legacy Fixture patterns to [Fact] methods
- →Replace SnapshotTest with MarkupMatches
- →Update component rendering syntax
How it works
The skill applies transformation rules to replace deprecated bUnit beta components and methods with modern 2.x stable API equivalents.
Inputs & outputs
When to use bunit-test-migration
- →Upgrade bUnit tests to 2.x
- →Replace TestComponentBase with BunitContext
- →Convert SnapshotTest patterns to [Fact] tests
- →Clean up legacy component testing code
About this skill
bUnit Test Migration Skill (Beta → 2.x)
This skill provides guidance for migrating test files from the deprecated bUnit 1.0.0-beta-10 API to bUnit 2.5.3 stable API. Use this when you encounter test files using the old TestComponentBase, <Fixture>, or <SnapshotTest> patterns.
When to Apply
Apply this skill when a .razor test file contains any of these patterns:
@inherits TestComponentBase<Fixture Test="..."><ComponentUnderTest><SnapshotTest>void MethodName(Fixture fixture)
Transformation Rules
1. Change Inheritance
- @inherits TestComponentBase
+ @inherits BunitContext
2. Remove Wrapper Elements
Remove these XML elements entirely (keep only the component inside):
- <Fixture Test="TestName">
- <ComponentUnderTest>
<MyComponent Parameter="value" />
- </ComponentUnderTest>
- </Fixture>
3. Convert Test Methods
- void TestMethodName(Fixture fixture)
+ [Fact]
+ public void ComponentName_Scenario_ExpectedResult()
4. Replace Component Access
- var cut = fixture.GetComponentUnderTest();
+ var cut = Render(@<MyComponent Parameter="value" />);
5. Convert Snapshot Tests
- <SnapshotTest Description="renders correctly">
- <TestInput>
- <MyComponent />
- </TestInput>
- <ExpectedOutput>
- <div>expected html</div>
- </ExpectedOutput>
- </SnapshotTest>
+ [Fact]
+ public void MyComponent_Default_RendersCorrectly()
+ {
+ var cut = Render(@<MyComponent />);
+ cut.MarkupMatches(@<div>expected html</div>);
+ }
Complete Example
Before
@inherits TestComponentBase
<Fixture Test="ShouldClickButton">
<ComponentUnderTest>
<Button OnClick="OnClick">Click me</Button>
</ComponentUnderTest>
</Fixture>
@code {
int ClickCount = 0;
void ShouldClickButton(Fixture fixture)
{
var cut = fixture.GetComponentUnderTest();
cut.Find("button").Click();
ClickCount.ShouldBe(1);
}
void OnClick() => ClickCount++;
}
After
@inherits BunitContext
@code {
int ClickCount = 0;
[Fact]
public void Button_Click_IncrementsCounter()
{
var cut = Render(@<Button OnClick="OnClick">Click me</Button>);
cut.Find("button").Click();
ClickCount.ShouldBe(1);
}
void OnClick() => ClickCount++;
}
Test Naming Convention
Pattern: ComponentName_Scenario_ExpectedResult
| Component | Scenario | Result | Test Name |
|---|---|---|---|
| Button | Click | InvokesHandler | Button_Click_InvokesHandler |
| DataList | EmptySource | ShowsEmptyTemplate | DataList_EmptySource_ShowsEmptyTemplate |
| GridView | WithData | RendersRows | GridView_WithData_RendersRows |
Special Patterns
Multiple Tests in One File
Each <Fixture> block becomes a separate [Fact] method:
@inherits BunitContext
@code {
[Fact]
public void Component_FirstScenario_ExpectedResult() { ... }
[Fact]
public void Component_SecondScenario_ExpectedResult() { ... }
}
Tests with Services
@code {
[Fact]
public void Component_WithService_Works()
{
Services.AddSingleton<IMyService>(new FakeService());
var cut = Render(@<MyComponent />);
}
}
Authentication Tests
@code {
[Fact]
public void SecureComponent_AuthenticatedUser_ShowsContent()
{
var authContext = this.AddTestAuthorization();
authContext.SetAuthorized("TestUser");
authContext.SetRoles("Admin");
var cut = Render(@<SecureComponent />);
}
}
Tests Requiring New TestContext
For tests that need isolated context (e.g., multiple renders):
@code {
[Fact]
public void Component_MultipleRenders_WorksCorrectly()
{
using var ctx = new Bunit.TestContext();
var cut1 = ctx.Render(@<MyComponent Value="1" />);
var cut2 = ctx.Render(@<MyComponent Value="2" />);
cut1.Find("span").TextContent.ShouldBe("1");
cut2.Find("span").TextContent.ShouldBe("2");
}
}
Tests with xUnit Logger (Optional)
For debugging complex tests, you can optionally enable xUnit logging:
@using Microsoft.Extensions.Logging
@code {
private ILogger<MyTest> _logger;
public MyTest(ITestOutputHelper output) : base(output)
{
}
[Fact]
public void Component_ComplexScenario_WorksAsExpected()
{
_logger = Services.GetService<ILogger<MyTest>>();
_logger?.LogInformation("Starting test");
var cut = Render(@<MyComponent />);
_logger?.LogDebug("Component rendered");
// Test assertions...
}
}
Note: Only add logging when diagnostic output is helpful. Most tests should remain simple without logging.
Quick Reference Table
| Old Pattern | New Pattern |
|---|---|
@inherits TestComponentBase | @inherits BunitContext |
<Fixture Test="Name"> | Remove |
<ComponentUnderTest> | Remove |
<SnapshotTest> | [Fact] method with MarkupMatches() |
void Name(Fixture fixture) | [Fact] public void Name() |
fixture.GetComponentUnderTest() | Render(@<Component />) |
fixture.GetComponentUnderTest<T>() | Render<T>(@<Component />) |
Verification
After migrating a file, verify with:
# Build check
dotnet build src/BlazorWebFormsComponents.Test --no-restore
# List discovered tests
dotnet test src/BlazorWebFormsComponents.Test --list-tests --filter "FullyQualifiedName~ComponentName"
# Run tests
dotnet test src/BlazorWebFormsComponents.Test --filter "FullyQualifiedName~ComponentName"
Common Errors
| Error | Cause | Fix |
|---|---|---|
CS0246: TestComponentBase not found | Old inheritance | Change to @inherits BunitContext |
CS0103: Fixture does not exist | Old wrapper element | Remove <Fixture> tags |
No tests discovered | Missing [Fact] attribute | Add [Fact] to test methods |
Method must be public | Private test method | Add public modifier |
When not to use it
- →For non-bUnit test files
- →When working with bUnit 1.x projects that cannot be upgraded
Prerequisites
Limitations
- →Only supports migration from 1.0.0-beta-10
- →Requires manual verification of test logic
How it compares
It automates the refactoring of obsolete test patterns, which would otherwise require manual, error-prone code updates.
Compared to similar skills
bunit-test-migration side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| bunit-test-migration (this skill) | 1 | 6mo | No flags | Beginner |
| csharp-pro | 9 | 4mo | No flags | Intermediate |
| performance-benchmark | 3 | 4mo | No flags | Intermediate |
| run-device-tests | 3 | 2mo | Review | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by FritzAndFriends
View all by FritzAndFriends →You might also like
csharp-pro
sickn33
Write modern C# code with advanced features like records, pattern matching, and async/await. Optimizes .NET applications, implements enterprise patterns, and ensures comprehensive testing. Use PROACTIVELY for C# refactoring, performance optimization, or complex .NET solutions.
performance-benchmark
dotnet
Generate and run ad hoc performance benchmarks to validate code changes. Use this when asked to benchmark, profile, or validate the performance impact of a code change in dotnet/runtime.
run-device-tests
dotnet
Build and run .NET MAUI device tests locally with category filtering. Supports iOS, MacCatalyst, Android on macOS; Android, Windows on Windows. Use TestFilter to run specific test categories.
backend-testing
exceptionless
Backend testing with xUnit, Foundatio.Xunit, integration tests with AppWebHostFactory, FluentClient, ProxyTimeProvider for time manipulation, and test data builders. Keywords: xUnit, Fact, Theory, integration tests, AppWebHostFactory, FluentClient, ProxyTimeProvider, TimeProvider, Foundatio.Xunit, TestWithLoggingBase, test data builders
deployment-e2e-testing
dotnet
Guide for writing Aspire deployment end-to-end tests. Use this when asked to create, modify, or debug deployment E2E tests that deploy to Azure.
component-development
FritzAndFriends
Guidance for creating Blazor components that emulate ASP.NET Web Forms controls. Use this when implementing new components or extending existing ones in the BlazorWebFormsComponents library.