Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ List of new features.
List of changes in existing functionality.

- `TestContextBase.Dispose` made virtual to allow inheritor's to override it. By [@SimonCropp](https://github.com/SimonCropp) in [#137](https://github.com/egil/bunit/pull/137).
- Changed naming convention for JSMock feature. All classes and methods containing `Js` (meaning JavaScript) renamed to `JS`. By [yourilima](https://github.com/yourilima) in [#150](https://github.com/egil/bUnit/pull/150)

### Deprecated
List of soon-to-be removed features.
Expand Down
24 changes: 12 additions & 12 deletions docs/site/docs/csharp-test-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -396,11 +396,11 @@ public class ThemedButtonTest : ComponentTestFixture
- `Test002` above uses the `CascadingValue(object value)` helper method to pass an **unnamed** cascading value to the CUT.
- `Test003` above demonstrates how multiple (named) cascading values can be passed to a component under test.

## Testing components that use on `IJsRuntime`
## Testing components that use on `IJSRuntime`

It is not uncommon to have components use Blazor's JSInterop functionality to call JavaScript, e.g. after first render.

To make it easy to mock calls to JavaScript, the library comes with a `IJsRuntime` mocking helper, that allows you to specify return how JSInterop calls should be handled, and to verify that they have happened.
To make it easy to mock calls to JavaScript, the library comes with a `IJSRuntime` mocking helper, that allows you to specify return how JSInterop calls should be handled, and to verify that they have happened.

If you have more complex mocking needs, you could look to frameworks like [Moq](https://github.com/Moq) or [JustMock Lite](https://github.com/telerik/JustMockLite), which both work nicely with bUnit.

Expand Down Expand Up @@ -441,10 +441,10 @@ public class WikiSearchTest : ComponentTestFixture
public void Test001()
{
// Arrange
// Registered the MockJsRuntime in "Loose" mode with the service provider used when rendering components.
// JsRuntimeMockMode.Loose is the default. It configures the mock to just return the default
// Registered the MockJSRuntime in "Loose" mode with the service provider used when rendering components.
// JSRuntimeMockMode.Loose is the default. It configures the mock to just return the default
// value for whatever is requested in a InvokeAsync call if no call has explicitly been set up.
var jsMock = Services.AddMockJsRuntime();
var jsMock = Services.AddMockJSRuntime();

// Act - render the WikiSearch component
var cut = RenderComponent<WikiSearch>();
Expand All @@ -460,10 +460,10 @@ public class WikiSearchTest : ComponentTestFixture
public void Test002()
{
// Arrange
// Registered the MockJsRuntime in "strict" mode with the service provider used when rendering components.
// JsRuntimeMockMode.Strict mode configures the mock to throw an error if it receives an InvokeAsync call
// Registered the MockJSRuntime in "strict" mode with the service provider used when rendering components.
// JSRuntimeMockMode.Strict mode configures the mock to throw an error if it receives an InvokeAsync call
// it has not been set up to handle.
var jsMock = Services.AddMockJsRuntime(JsRuntimeMockMode.Strict);
var jsMock = Services.AddMockJSRuntime(JSRuntimeMockMode.Strict);

// Set up the mock to handle the expected call
var expectedSearchResult = "SEARCH RESULT";
Expand All @@ -486,7 +486,7 @@ public class WikiSearchTest : ComponentTestFixture
}
```

- `Test001` just injects the mock in "Loose" mode. It means it will only returns a `default(TValue)` for calls to `InvokeAsync<TValue>(...)` it receives. This allows us to test components that expects a `IJsRuntime` to be injected, but where the test we want to perform isn't dependent on it providing any specific return value.
- `Test001` just injects the mock in "Loose" mode. It means it will only returns a `default(TValue)` for calls to `InvokeAsync<TValue>(...)` it receives. This allows us to test components that expects a `IJSRuntime` to be injected, but where the test we want to perform isn't dependent on it providing any specific return value.

In "Loose" mode it is still possible to call `VerifyInvoke(identifier)` and assert against the expected invocation.

Expand All @@ -497,7 +497,7 @@ public class WikiSearchTest : ComponentTestFixture

### Verifying element references passed to InvokeAsync

If you want to verify that a element reference (`ElementReference`) passed to a IJsRuntime.InvokeAsync call is references the expected DOM element, you can do so with the `ShouldBeElementReferenceTo()` assert helper.
If you want to verify that a element reference (`ElementReference`) passed to a IJSRuntime.InvokeAsync call is references the expected DOM element, you can do so with the `ShouldBeElementReferenceTo()` assert helper.

For example, consider the [FocussingInput.razor](https://github.com/egil/razor-components-testing-library/tree/main/sample/src/Components/FocussingInput.razor) component, which looks like this:

Expand Down Expand Up @@ -530,8 +530,8 @@ public class FocussingInputTest : ComponentTestFixture
[Fact(DisplayName = "After first render, the new input field has focus")]
public void Test001()
{
// Arrange - add the IJsRuntime mock
var jsRtMock = Services.AddMockJsRuntime();
// Arrange - add the IJSRuntime mock
var jsRtMock = Services.AddMockJSRuntime();

// Act - render the FocussingInput component, causing
// the OnAfterRender(firstRender: true) to be called
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
@inherits TestComponentBase

@code {
MockJsRuntimeInvokeHandler MockJsRuntime { get; set; } = default!;
MockJSRuntimeInvokeHandler MockJSRuntime { get; set; } = default!;

void Setup(Fixture fixture)
{
MockJsRuntime = fixture.Services.AddMockJsRuntime();
MockJSRuntime = fixture.Services.AddMockJSRuntime();
}
}

Expand Down Expand Up @@ -190,7 +190,7 @@
void Test007(Fixture fixture)
{
// arrange
var plannedInvocation = MockJsRuntime.Setup<object>("window.transitionFinished");
var plannedInvocation = MockJSRuntime.Setup<object>("window.transitionFinished");
var cut = fixture.GetComponentUnderTest<Alert>();

// Act
Expand Down
10 changes: 5 additions & 5 deletions sample/tests/RazorTestComponents/Components/TodoListTest.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@inherits TestComponentBase

<Fixture Setup="(fixture) => fixture.Services.AddMockJsRuntime()"
<Fixture Setup="(fixture) => fixture.Services.AddMockJSRuntime()"
Test="EmptyTodoListRendersCorrectly">
<ComponentUnderTest>
<TodoList>
Expand Down Expand Up @@ -36,7 +36,7 @@
}
</Fixture>

<Fixture Setup="(fixture) => fixture.Services.AddMockJsRuntime()"
<Fixture Setup="(fixture) => fixture.Services.AddMockJSRuntime()"
Test="SettingLabelRendersCorrectly">
<ComponentUnderTest>
<TodoList>
Expand Down Expand Up @@ -65,7 +65,7 @@
}
</Fixture>

<Fixture Setup="(fixture) => fixture.Services.AddMockJsRuntime()"
<Fixture Setup="(fixture) => fixture.Services.AddMockJSRuntime()"
Test="TaskListRendersItemsUsingItemTemplate">
<ComponentUnderTest>
<TodoList>
Expand Down Expand Up @@ -101,14 +101,14 @@
</Fixture>

@code {
MockJsRuntimeInvokeHandler jsRtMock = default!;
MockJSRuntimeInvokeHandler jsRtMock = default!;
Todo? createdTodo;

void OnAddingTodoHandler(Todo todo) => createdTodo = todo;

void Setup(Fixture fixture)
{
jsRtMock = fixture.Services.AddMockJsRuntime();
jsRtMock = fixture.Services.AddMockJSRuntime();
}
}

Expand Down
2 changes: 1 addition & 1 deletion sample/tests/SampleApp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="bunit" Version="1.0.0-beta-7" />
<PackageReference Include="bunit" Version="1.0.0-beta-8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="Shouldly" Version="3.0.2" />
Expand Down
2 changes: 1 addition & 1 deletion sample/tests/SnapshotTests/AlertSnapshotTest.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@inherits TestComponentBase

<SnapshotTest Setup="(test) => test.Services.AddMockJsRuntime()"
<SnapshotTest Setup="(test) => test.Services.AddMockJSRuntime()"
Description="Alert renders correctly when all input is provided">
<TestInput>
<Alert Header="It is time to focus on Blazor">
Expand Down
2 changes: 1 addition & 1 deletion sample/tests/SnapshotTests/TodoListTest.razor
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@inherits TestComponentBase

<SnapshotTest Description="A todolist with one todo added should render correctly"
Setup="(test) => test.Services.AddMockJsRuntime()">
Setup="(test) => test.Services.AddMockJSRuntime()">
<TestInput>
<TodoList Label="My label" Items=@(new Todo[]{ new Todo{ Id=42, Text="Check out this new thing called Blazor" } })>
<ItemsTemplate Context="todo">
Expand Down
12 changes: 6 additions & 6 deletions sample/tests/Tests/Components/AlertTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using System;
using System.Threading.Tasks;
using Bunit.Mocking.JSInterop;
using Bunit.TestDoubles.JSInterop;
using SampleApp.Components;
using SampleApp.Data;
using Microsoft.AspNetCore.Authentication;
Expand All @@ -13,11 +13,11 @@ namespace SampleApp.Tests.Components
{
public class AlertTest2 : TestContext
{
MockJsRuntimeInvokeHandler MockJsRuntime { get; }
MockJSRuntimeInvokeHandler MockJSRuntime { get; }

public AlertTest2()
{
MockJsRuntime = Services.AddMockJsRuntime();
MockJSRuntime = Services.AddMockJSRuntime();
}

[Fact(DisplayName = "Given no parameters, " +
Expand Down Expand Up @@ -156,8 +156,8 @@ public void Test006()
public void Test()
{
// Arrange
var mockJsRuntime = Services.AddMockJsRuntime();
var plannedInvocation = mockJsRuntime.Setup<object>("window.transitionFinished");
var mockJSRuntime = Services.AddMockJSRuntime();
var plannedInvocation = mockJSRuntime.Setup<object>("window.transitionFinished");

DismissingEventArgs? dismissingEvent = default;
Alert? dismissedAlert = default;
Expand Down Expand Up @@ -191,7 +191,7 @@ public void Test()
public void Test007()
{
// Arrange
var plannedInvocation = MockJsRuntime.Setup<object>("window.transitionFinished");
var plannedInvocation = MockJSRuntime.Setup<object>("window.transitionFinished");
var cut = RenderComponent<Alert>();

// Act - click the button
Expand Down
6 changes: 3 additions & 3 deletions sample/tests/Tests/Components/FocussingInputTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bunit.Mocking.JSInterop;
using Bunit.TestDoubles.JSInterop;
using SampleApp.Components;
using Xunit;
using Bunit;
Expand All @@ -16,8 +16,8 @@ public class FocussingInputTest : TestContext
[Fact(DisplayName = "After first render, the new input field has focus")]
public void Test001()
{
// Arrange - add the IJsRuntime mock
var jsRtMock = Services.AddMockJsRuntime();
// Arrange - add the IJSRuntime mock
var jsRtMock = Services.AddMockJSRuntime();

// Act - render the FocussingInput component, causing
// the OnAfterRender(firstRender: true) to be called
Expand Down
16 changes: 8 additions & 8 deletions sample/tests/Tests/Components/TodoListTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Shouldly;
using AngleSharp.Dom;
using Bunit.Mocking.JSInterop;
using Bunit.TestDoubles.JSInterop;
using SampleApp.Components;
using SampleApp.Data;
using Microsoft.AspNetCore.Components;
Expand Down Expand Up @@ -34,7 +34,7 @@ private string GetExpectedHtml(string label = "Task description", string itemsHt
public void Test001()
{
// arrange
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();

// act
var cut = RenderComponent<TodoList>();
Expand All @@ -47,7 +47,7 @@ public void Test001()
public void Test002()
{
// arrange
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();
var label = "hello world";

// act
Expand All @@ -61,7 +61,7 @@ public void Test002()
public void Test003()
{
// arrange
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();
RenderFragment<Todo> itemTemplate = todo => builder => builder.AddMarkupContent(0, $"<li>{todo.Id}</li>");
var items = new[] { new Todo { Id = 42 }, new Todo { Id = 1337 } };

Expand All @@ -80,7 +80,7 @@ public void Test003()
public void Test004()
{
// arrange
var jsRtMock = Services.AddMockJsRuntime();
var jsRtMock = Services.AddMockJSRuntime();

// act
var cut = RenderComponent<TodoList>();
Expand All @@ -95,7 +95,7 @@ public void Test004()
public void Test0041()
{
// arrange
var jsRtMock = Services.AddMockJsRuntime();
var jsRtMock = Services.AddMockJSRuntime();

// act
var cut = RenderComponent<TodoList>(); // first render
Expand All @@ -110,7 +110,7 @@ public void Test0041()
"the OnAddingTodo is raised with a new Todo containing the entered text")]
public void Test005()
{
var jsRtMock = Services.AddMockJsRuntime();
var jsRtMock = Services.AddMockJSRuntime();
var taskValue = "HELLO WORLD TASK";
var createdTask = default(Todo);
var cut = RenderComponent<TodoList>(
Expand All @@ -127,7 +127,7 @@ public void Test005()
[Fact(DisplayName = "When add task form is submitted with no text OnAddingTodo is not called")]
public void Test006()
{
var jsRtMock = Services.AddMockJsRuntime();
var jsRtMock = Services.AddMockJSRuntime();
var createdTask = default(Todo);
var cut = RenderComponent<TodoList>(
EventCallback<Todo>(nameof(TodoList.OnAddingTodo), task => createdTask = task)
Expand Down
14 changes: 7 additions & 7 deletions sample/tests/Tests/Components/WikiSearchTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;
using SampleApp.Components;
using Bunit.Mocking.JSInterop;
using Bunit.TestDoubles.JSInterop;
using Shouldly;
using Xunit;
using Bunit;
Expand All @@ -18,10 +18,10 @@ public class WikiSearchTest : TestContext
public void Test001()
{
// Arrange
// Registered the MockJsRuntime in "Loose" mode with the service provider used when rendering components.
// JsRuntimeMockMode.Loose is the default. It configures the mock to just return the default
// Registered the MockJSRuntime in "Loose" mode with the service provider used when rendering components.
// JSRuntimeMockMode.Loose is the default. It configures the mock to just return the default
// value for whatever is requested in a InvokeAsync call if no call has explicitly been set up.
var jsMock = Services.AddMockJsRuntime();
var jsMock = Services.AddMockJSRuntime();

// Act - render the WikiSearch component
var cut = RenderComponent<WikiSearch>();
Expand All @@ -37,10 +37,10 @@ public void Test001()
public void Test002()
{
// Arrange
// Registered the MockJsRuntime in "strict" mode with the service provider used when rendering components.
// JsRuntimeMockMode.Strict mode configures the mock to throw an error if it receives an InvokeAsync call
// Registered the MockJSRuntime in "strict" mode with the service provider used when rendering components.
// JSRuntimeMockMode.Strict mode configures the mock to throw an error if it receives an InvokeAsync call
// it has not been set up to handle.
var jsMock = Services.AddMockJsRuntime(JsRuntimeMockMode.Strict);
var jsMock = Services.AddMockJSRuntime(JSRuntimeMockMode.Strict);

// Set up the mock to handle the expected call
var expectedSearchResult = "SEARCH RESULT";
Expand Down
4 changes: 2 additions & 2 deletions sample/tests/Tests/Pages/TodosTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
using SampleApp.Data;
using SampleApp.Pages;
using Microsoft.Extensions.DependencyInjection;
using Bunit.Mocking.JSInterop;
using Bunit.TestDoubles.JSInterop;
using Bunit;

namespace SampleApp.CodeOnlyTests.Pages
Expand All @@ -18,7 +18,7 @@ public class TodosTest : TestContext
{
public TodosTest()
{
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();
}

[Fact(DisplayName = "Renders Todos provided by todo service")]
Expand Down
2 changes: 1 addition & 1 deletion sample/tests/_Imports.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@using Microsoft.Extensions.DependencyInjection

@using Bunit
@using Bunit.Mocking.JSInterop
@using Bunit.TestDoubles.JSInterop
@using SampleApp
@using SampleApp.Data
@using SampleApp.Components
Expand Down
6 changes: 3 additions & 3 deletions src/bunit.core.tests/ComponentParameterFactoryTest.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using Bunit.Mocking.JSInterop;
using Bunit.Rendering;
using Bunit.TestAssets.SampleComponents;
using Bunit.TestDoubles.JSInterop;
using Shouldly;

using Xunit;
Expand All @@ -16,7 +16,7 @@ public class ComponentParameterFactoryTest : TestContext
[Fact(DisplayName = "All types of parameters are correctly assigned to component on render")]
public void Test005()
{
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();

var cut = RenderComponent<AllTypesOfParams<string>>(
("some-unmatched-attribute", "unmatched value"),
Expand Down Expand Up @@ -48,7 +48,7 @@ public void Test005()
public void Test002()
{
// arrange
Services.AddMockJsRuntime();
Services.AddMockJSRuntime();
var cut = RenderComponent<AllTypesOfParams<string>>();

// assert that no parameters have been set initially
Expand Down
Loading