Skip to content

Commit 4e7e451

Browse files
committed
Docs: added fixture options
1 parent b1d6ccb commit 4e7e451

4 files changed

Lines changed: 86 additions & 12 deletions

File tree

docs/docs.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
<RazorLangVersion>3.0</RazorLangVersion>
66
</PropertyGroup>
77

8+
<ItemGroup>
9+
<None Remove="samples\tests\razor\FixtureWithCutAndFragments.html" />
10+
</ItemGroup>
11+
12+
<ItemGroup>
13+
<Content Include="samples\tests\razor\FixtureWithCutAndFragments.html" />
14+
</ItemGroup>
15+
816
<ItemGroup>
917
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.4" />
1018
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.4" />

docs/docs/getting-started/fixture-options.md

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,16 @@ All the parameters the `<Fixture>` support is shown in the listing below:
1919
Let us start by looking at the parameters that takes a method as input first. The methods are called in the order they are listed in below, if provided, and should be used to the following:
2020

2121
1. **<xref:Bunit.RazorTesting.FixtureBase`1.Setup>** and **<xref:Bunit.RazorTesting.FixtureBase`1.SetupAsync>:**
22-
The `Setup` and `SetupAsync` method is called first, and you can provide both if needed. If both are provided, `Setup` is called first.
23-
They allows you to configures e.g. the <xref:Bunit.ITestContext.Services> collection of the <xref:Bunit.Fixture> component before the component under test or any fragments are rendered.
22+
The `Setup` and `SetupAsync` methods are called first, and you can provide both if needed. If both are provided, `Setup` is called first.
23+
They are usually used to configure the <xref:Bunit.ITestContext.Services> collection of the <xref:Bunit.Fixture> component before the component under test or any fragments are rendered.
2424
2. **<xref:Bunit.RazorTesting.FixtureBase`1.Test>** or **<xref:Bunit.RazorTesting.FixtureBase`1.TestAsync>:**
25-
The `Test` or `TestAsync` methods are called after the setup methods.
26-
_One, and only one,_ of the test methods must be specified. Use the test method to access the component under test and any fragments defined in the fixture and interact and assert against them.
25+
The `Test` or `TestAsync` method is called after the setup methods.
26+
_One, and only one_ of the test methods can be specified per fixture. Use the test method to access the component under test and any fragments defined in the fixture and interact and assert against them.
2727

28+
In the example above, the setup and test methods are declared in a `@code { }` block nested inside the <xref:Bunit.Fixture> component. This visually groups the methods nicely to the <xref:Bunit.Fixture> component, but it's not a requirement.
29+
30+
You can have the methods anywhere inside the test component you want, which can be useful, if you for example have a common setup method that multiple Razor tests in the same test component shares. The methods can also be declared in the parameter directly, e.g.: `<Fixture Setup="f => f.Services.AddMockJsRuntime" ...>`.
31+
2832
**Other parameters**
2933

3034
The other parameters affect how the test runs, and how it is displayed in e.g. Visual Studio's Test Explorer:
@@ -34,10 +38,52 @@ The other parameters affect how the test runs, and how it is displayed in e.g. V
3438
2. **<xref:Bunit.RazorTesting.RazorTestBase.Skip>:**
3539
If the skip parameter is provided, the test is skipped and the text entered in the skip parameter is passed to the test runner as the reason to skip the test.
3640
3. **<xref:Bunit.RazorTesting.RazorTestBase.Timeout>:**
37-
If provided, the test runner will terminate the test after the specified amount of time.
41+
If provided, the test runner will terminate the test after the specified amount of time, if it has not completed already.
3842

3943
## `<ComponentUnderTest>` and `<Fragment>`
4044

41-
## Getting `<ComponentUnderTest>` and `<Fragment>`
45+
The <xref:Bunit.Fixture> component only accepts the <xref:Bunit.ComponentUnderTest> and <xref:Bunit.Fragment> components as its child content. All other components and markup are ignored. E.g.:
46+
47+
[!code-html[](../../samples/tests/razor/FixtureWithCutAndFragments.html)]
48+
49+
Here are the rules for the <xref:Bunit.Fixture> components child content:
50+
51+
1. One <xref:Bunit.ComponentUnderTest> component must be added, and it should not be empty.
52+
2. Zero or more <xref:Bunit.Fragment> components can be added.
53+
3. The order the <xref:Bunit.ComponentUnderTest> and <xref:Bunit.Fragment> components are added in does not matter.
54+
4. The <xref:Bunit.ComponentUnderTest> and <xref:Bunit.Fragment> components can contain both Razor markup and regular HTML markup.
55+
5. If more than one <xref:Bunit.Fragment> component is added, give each fragment an `Id` to be able to identify them when retrieving them in the test method.
56+
6. The first <xref:Bunit.Fragment> component is added can always be retrieved without an id.
57+
58+
## Getting `<ComponentUnderTest>` and `<Fragment>` in the Test Methods
59+
60+
The <xref:Bunit.Fixture>'s setup and test methods receives the <xref:Bunit.Fixture> instance as input when they are called. It is through it, the <xref:Bunit.Fixture> instance, we can get the component under test and any fragments declared inside it. The relevant methods comes in both a generic and non-generic variants:
61+
62+
- **<xref:Bunit.Fixture.GetComponentUnderTest>:**
63+
Use this to return an <xref:Bunit.IRenderedFragment>, which represents the content declared inside the <xref:Bunit.ComponentUnderTest> component. A <xref:Bunit.IRenderedFragment> does not give you access to the instance of the component under test, but it does give you access to the rendered markup.
64+
65+
- **<xref:Bunit.Fixture.GetComponentUnderTest``1>:**
66+
Use this to return an <xref:Bunit.IRenderedComponent`1>, which represents a component of type `TComponent` declared inside the <xref:Bunit.ComponentUnderTest> component. The <xref:Bunit.IRenderedComponent`1> does give you access to the `TComponent` instance, as well as the rendered markup of it.
67+
68+
- **<xref:Bunit.Fixture.GetFragment(System.String)>:**
69+
Use this to get a <xref:Bunit.IRenderedFragment>, which represents the content declared inside the <xref:Bunit.Fragment> component.
70+
71+
- **<xref:Bunit.Fixture.GetFragment``1(System.String)>**
72+
Use this to return an <xref:Bunit.IRenderedComponent`1>, which represents a component of type `TComponent` declared inside the <xref:Bunit.Fragment> component.
73+
74+
For both the `GetFragment` methods the `id` string parameter is optional. If it is not provided, the first <xref:Bunit.Fragment> is used to return a <xref:Bunit.IRenderedFragment> or <xref:Bunit.IRenderedComponent`1>. Otherwise, the <xref:Bunit.Fragment> with an `Id` parameter that matches the `id` specified in the `GetFragment` method call will be used.
75+
76+
The generic versions of <xref:Bunit.Fixture.GetComponentUnderTest``1> and <xref:Bunit.Fixture.GetFragment``1(System.String)> can specify a component of type `TComponent` that is not the first child of <xref:Bunit.ComponentUnderTest> or <xref:Bunit.Fragment>. This is useful if e.g. the component under test is wrapped inside a `<CascadingValue>`. The methods will return the _first_ component it finds that matches the requested type, through a depth-first search of the render tree.
77+
78+
> [!NOTE]
79+
> You can call the `GetComponentUnderTest` or `GetFragment` methods multiple times on the same `Fixture` instance. Each time will return the same instance for the same input. However, you cannot mix the generic and non-generic versions.
80+
81+
## Example
82+
83+
TODO:
4284

43-
## Example
85+
1. Create a basic component that takes a cascading value, a service, and maybe some child content, and it should have a initial rendered output and something after e.g. a click event.
86+
2. Add a setup method that registers the service
87+
3. Add two fragments, one to verify the inital rendered output and one for the output after click.
88+
4. Show how GetCompnentUnderTest returns not the cascading value
89+
5. Show how get fragment is used with and without id, and returns fragments without
Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1-
<Fixture Setup="fixture => { }"
2-
SetupAsync="fixture => Task.CompletedTask"
3-
Test="fixture => { }"
4-
TestAsync="fixture => Task.CompletedTask"
1+
<Fixture Setup=@Setup
2+
SetupAsync=@SetupAsync
3+
Test=@Test
4+
TestAsync=@TestAsync
55
Description="Description of test"
66
Timeout="TimeSpan.FromSeconds(2)"
77
Skip="Reason to skip the test">
8-
...
8+
9+
@code
10+
{
11+
void Setup(Fixture fixture) { }
12+
Task SetupAsync(Fixture fixture) => Task.CompletedTask;
13+
// NOTE: Only one of Test/TestAsync can be used at the same time.
14+
// Both are included here for illustration purposes only.
15+
void Test(Fixture fixture) { }
16+
Task TestAsync(Fixture fixture) => Task.CompletedTask;
17+
}
918
</Fixture>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<Fixture Test="...">
2+
<ComponentUnderTest>
3+
<!-- Razor or HTML markup goes here -->
4+
</ComponentUnderTest>
5+
<Fragment>
6+
<!-- Razor or HTML markup goes here -->
7+
</Fragment>
8+
<Fragment Id="some id">
9+
<!-- Razor or HTML markup goes here -->
10+
</Fragment>
11+
</Fixture>

0 commit comments

Comments
 (0)