Skip to content

Commit 7411c68

Browse files
Siphonophoraegil
andcommitted
Add default JsRuntime (#32)
* Add default JsRuntime * Update src/Mocking/JSInterop/DefaultJsRuntime.cs Co-Authored-By: Egil Hansen <[email protected]> * Response to review. Add custom exception and code cleanup * Remove unneded method * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> * Update src/Mocking/JSInterop/MissingMockJsRuntimeException.cs Co-Authored-By: Egil Hansen <[email protected]> Co-authored-by: Egil Hansen <[email protected]>
1 parent c78be10 commit 7411c68

File tree

5 files changed

+109
-2
lines changed

5 files changed

+109
-2
lines changed

src/Assembly.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Egil.RazorComponents.Testing.Library.Tests")]
1+
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Egil.RazorComponents.Testing.Library.Tests")]
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using System.Diagnostics.CodeAnalysis;
7+
8+
namespace Egil.RazorComponents.Testing
9+
{
10+
/// <summary>
11+
/// Exception use to indicate that a MockJsRuntime is required by a test
12+
/// but was not provided.
13+
/// </summary>
14+
[SuppressMessage("Design", "CA1032:Implement standard exception constructors", Justification = "<Pending>")]
15+
public class MissingMockJsRuntimeException : Exception
16+
{
17+
/// <summary>
18+
/// Identifer string used in the JSInvoke method.
19+
/// </summary>
20+
public string Identifier { get; }
21+
22+
/// <summary>
23+
/// Arguments passed to the JSInvoke method.
24+
/// </summary>
25+
public IReadOnlyList<object> Arguments { get; }
26+
27+
/// <summary>
28+
/// Creates a new instance of the <see cref="MissingMockJsRuntimeException"/>
29+
/// with the arguments used in the invocation.
30+
/// </summary>
31+
/// <param name="identifier">The identifer used in the invocation.</param>
32+
/// <param name="arguments">The args used in the invocation, if any</param>
33+
public MissingMockJsRuntimeException(string identifier, object[] arguments)
34+
: base($"This test requires a IJsRuntime to be supplied, because the component under test invokes the IJsRuntime during the test. The invoked method is '{identifier}' and the invocation arguments are stored in the {nameof(Arguments)} property of this exception. Guidance on mocking the IJsRuntime is available in the testing library's Wiki.")
35+
{
36+
Identifier = identifier;
37+
Arguments = arguments;
38+
HelpLink = "https://github.com/egil/razor-components-testing-library/wiki/Mocking-JsRuntime";
39+
}
40+
}
41+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading;
6+
using System.Threading.Tasks;
7+
using Microsoft.JSInterop;
8+
9+
namespace Egil.RazorComponents.Testing.Mocking.JSInterop
10+
{
11+
/// <summary>
12+
/// This JsRuntime is used to provide users with helpful exceptions if they fail to provide a mock when required.
13+
/// </summary>
14+
internal class PlaceholderJsRuntime : IJSRuntime
15+
{
16+
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, object[] args)
17+
{
18+
throw new MissingMockJsRuntimeException(identifier, args);
19+
}
20+
21+
public ValueTask<TValue> InvokeAsync<TValue>(string identifier, CancellationToken cancellationToken, object[] args)
22+
{
23+
throw new MissingMockJsRuntimeException(identifier, args);
24+
}
25+
}
26+
}

src/TestServiceProvider.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Microsoft.Extensions.DependencyInjection;
1+
using Egil.RazorComponents.Testing.Mocking.JSInterop;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.JSInterop;
24
using System;
35
using System.Diagnostics.CodeAnalysis;
46

@@ -13,6 +15,11 @@ public sealed class TestServiceProvider : IServiceProvider, IDisposable
1315
private readonly ServiceCollection _serviceCollection = new ServiceCollection();
1416
private ServiceProvider? _serviceProvider;
1517

18+
public TestServiceProvider()
19+
{
20+
_serviceCollection.AddSingleton<IJSRuntime, PlaceholderJsRuntime>();
21+
}
22+
1623
/// <summary>
1724
/// Gets whether this <see cref="TestServiceProvider"/> has been initialized, and
1825
/// no longer will accept calls to the <c>AddService</c>'s methods.

tests/TestServiceProviderTest.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Egil.RazorComponents.Testing.EventDispatchExtensions;
2+
using Egil.RazorComponents.Testing.Extensions;
3+
using Egil.RazorComponents.Testing.Mocking.JSInterop;
4+
using Egil.RazorComponents.Testing.SampleComponents;
5+
using Egil.RazorComponents.Testing.SampleComponents.Data;
6+
using Shouldly;
7+
using System;
8+
using System.Collections.Generic;
9+
using System.Linq;
10+
using System.Text;
11+
using Xunit;
12+
13+
namespace Egil.RazorComponents.Testing
14+
{
15+
public class TestServiceProviderTest : ComponentTestFixture
16+
{
17+
[Fact(DisplayName = "The test service provider should register a placeholder IJSRuntime " +
18+
"which throws exceptions")]
19+
public void Test001()
20+
{
21+
var ex = Assert.Throws<AggregateException>(() => RenderComponent<SimpleWithJsRuntimeDep>());
22+
Assert.True(ex?.InnerException is MissingMockJsRuntimeException);
23+
}
24+
25+
[Fact(DisplayName = "The placeholder IJSRuntime is overriden by a supplied mock and does not throw")]
26+
public void Test002()
27+
{
28+
Services.AddMockJsRuntime();
29+
30+
RenderComponent<SimpleWithJsRuntimeDep>();
31+
}
32+
}
33+
}

0 commit comments

Comments
 (0)