Skip to content

Commit 6de5e09

Browse files
committed
Changed WaitFor* rethrows unhandled exception tests to be more stable in environments with different performance characteristics
1 parent 0150d4f commit 6de5e09

File tree

1 file changed

+136
-136
lines changed

1 file changed

+136
-136
lines changed

tests/bunit.core.tests/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensionsTest.cs

Lines changed: 136 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -9,140 +9,140 @@
99

1010
namespace Bunit.Extensions.WaitForHelpers
1111
{
12-
public class RenderedFragmentWaitForHelperExtensionsTest : TestContext
13-
{
14-
public RenderedFragmentWaitForHelperExtensionsTest(ITestOutputHelper testOutput)
15-
{
16-
Services.AddXunitLogger(testOutput);
17-
}
18-
19-
[Fact(DisplayName = "WaitForAssertion can wait for multiple renders and changes to occur")]
20-
public void Test110()
21-
{
22-
// Initial state is stopped
23-
var cut = RenderComponent<TwoRendersTwoChanges>();
24-
var stateElement = cut.Find("#state");
25-
stateElement.TextContent.ShouldBe("Stopped");
26-
27-
// Clicking 'tick' changes the state, and starts a task
28-
cut.Find("#tick").Click();
29-
cut.Find("#state").TextContent.ShouldBe("Started");
30-
31-
// Clicking 'tock' completes the task, which updates the state
32-
// This click causes two renders, thus something is needed to await here.
33-
cut.Find("#tock").Click();
34-
cut.WaitForAssertion(() => cut.Find("#state").TextContent.ShouldBe("Stopped"));
35-
}
36-
37-
[Fact(DisplayName = "WaitForAssertion throws assertion exception after timeout")]
38-
public void Test011()
39-
{
40-
var cut = RenderComponent<Simple1>();
41-
42-
var expected = Should.Throw<WaitForFailedException>(() =>
43-
cut.WaitForAssertion(() => cut.Markup.ShouldBeEmpty(), TimeSpan.FromMilliseconds(10)));
44-
45-
expected.Message.ShouldBe(WaitForAssertionHelper.TimeoutMessage);
46-
expected.InnerException.ShouldBeOfType<ShouldAssertException>();
47-
}
48-
49-
[Fact(DisplayName = "WaitForState throws exception after timeout")]
50-
public void Test012()
51-
{
52-
var cut = RenderComponent<Simple1>();
53-
54-
var expected = Should.Throw<WaitForFailedException>(() =>
55-
cut.WaitForState(() => string.IsNullOrEmpty(cut.Markup), TimeSpan.FromMilliseconds(100)));
56-
57-
expected.Message.ShouldBe(WaitForStateHelper.TimeoutBeforePassMessage);
58-
}
59-
60-
[Fact(DisplayName = "WaitForState throws exception if statePredicate throws on a later render")]
61-
public void Test013()
62-
{
63-
const string expectedInnerMessage = "INNER MESSAGE";
64-
var cut = RenderComponent<TwoRendersTwoChanges>();
65-
cut.Find("#tick").Click();
66-
cut.Find("#tock").Click();
67-
68-
var expected = Should.Throw<WaitForFailedException>(() =>
69-
cut.WaitForState(() =>
70-
{
71-
if (cut.Find("#state").TextContent == "Stopped")
72-
throw new InvalidOperationException(expectedInnerMessage);
73-
return false;
74-
}));
75-
76-
expected.Message.ShouldBe(WaitForStateHelper.ExceptionInPredicateMessage);
77-
expected.InnerException.ShouldBeOfType<InvalidOperationException>()
78-
.Message.ShouldBe(expectedInnerMessage);
79-
}
80-
81-
[Fact(DisplayName = "WaitForState can wait for multiple renders and changes to occur")]
82-
public void Test100()
83-
{
84-
// Initial state is stopped
85-
var cut = RenderComponent<TwoRendersTwoChanges>();
86-
87-
// Clicking 'tick' changes the state, and starts a task
88-
cut.Find("#tick").Click();
89-
cut.Find("#state").TextContent.ShouldBe("Started");
90-
91-
// Clicking 'tock' completes the task, which updates the state
92-
// This click causes two renders, thus something is needed to await here.
93-
cut.Find("#tock").Click();
94-
cut.WaitForState(() =>
95-
{
96-
var elm = cut.Nodes.QuerySelector("#state");
97-
return elm?.TextContent == "Stopped";
98-
});
99-
}
100-
101-
[Fact(DisplayName = "WaitForState can detect async changes to properties in the CUT")]
102-
public void Test200()
103-
{
104-
var cut = RenderComponent<AsyncRenderChangesProperty>();
105-
cut.Instance.Counter.ShouldBe(0);
106-
107-
// Clicking 'tick' changes the counter, and starts a task
108-
cut.Find("#tick").Click();
109-
cut.Instance.Counter.ShouldBe(1);
110-
111-
// Clicking 'tock' completes the task, which updates the counter
112-
// This click causes two renders, thus something is needed to await here.
113-
cut.Find("#tock").Click();
114-
cut.WaitForState(() => cut.Instance.Counter == 2);
115-
116-
cut.Instance.Counter.ShouldBe(2);
117-
}
118-
119-
[Fact(DisplayName = "WaitForAssertion rethrows unhandled exception from a components async operation's methods")]
120-
public void Test300()
121-
{
122-
var cut = RenderComponent<ThrowsAfterAsyncOperation>();
123-
124-
Should.Throw<ThrowsAfterAsyncOperation.ThrowsAfterAsyncOperationException>(
125-
() => cut.WaitForAssertion(() => false.ShouldBeTrue()));
126-
}
127-
128-
[Fact(DisplayName = "WaitForState rethrows unhandled exception from components async operation's methods")]
129-
public void Test301()
130-
{
131-
var cut = RenderComponent<ThrowsAfterAsyncOperation>();
132-
133-
Should.Throw<ThrowsAfterAsyncOperation.ThrowsAfterAsyncOperationException>(
134-
() => cut.WaitForState(() => false));
135-
}
136-
137-
internal class ThrowsAfterAsyncOperation : ComponentBase
138-
{
139-
protected override async Task OnInitializedAsync()
140-
{
141-
await Task.Delay(1);
142-
throw new ThrowsAfterAsyncOperationException();
143-
}
144-
145-
internal sealed class ThrowsAfterAsyncOperationException : Exception { }
146-
}
147-
}
12+
public class RenderedFragmentWaitForHelperExtensionsTest : TestContext
13+
{
14+
public RenderedFragmentWaitForHelperExtensionsTest(ITestOutputHelper testOutput)
15+
{
16+
Services.AddXunitLogger(testOutput);
17+
}
18+
19+
[Fact(DisplayName = "WaitForAssertion can wait for multiple renders and changes to occur")]
20+
public void Test110()
21+
{
22+
// Initial state is stopped
23+
var cut = RenderComponent<TwoRendersTwoChanges>();
24+
var stateElement = cut.Find("#state");
25+
stateElement.TextContent.ShouldBe("Stopped");
26+
27+
// Clicking 'tick' changes the state, and starts a task
28+
cut.Find("#tick").Click();
29+
cut.Find("#state").TextContent.ShouldBe("Started");
30+
31+
// Clicking 'tock' completes the task, which updates the state
32+
// This click causes two renders, thus something is needed to await here.
33+
cut.Find("#tock").Click();
34+
cut.WaitForAssertion(() => cut.Find("#state").TextContent.ShouldBe("Stopped"));
35+
}
36+
37+
[Fact(DisplayName = "WaitForAssertion throws assertion exception after timeout")]
38+
public void Test011()
39+
{
40+
var cut = RenderComponent<Simple1>();
41+
42+
var expected = Should.Throw<WaitForFailedException>(() =>
43+
cut.WaitForAssertion(() => cut.Markup.ShouldBeEmpty(), TimeSpan.FromMilliseconds(10)));
44+
45+
expected.Message.ShouldBe(WaitForAssertionHelper.TimeoutMessage);
46+
expected.InnerException.ShouldBeOfType<ShouldAssertException>();
47+
}
48+
49+
[Fact(DisplayName = "WaitForState throws exception after timeout")]
50+
public void Test012()
51+
{
52+
var cut = RenderComponent<Simple1>();
53+
54+
var expected = Should.Throw<WaitForFailedException>(() =>
55+
cut.WaitForState(() => string.IsNullOrEmpty(cut.Markup), TimeSpan.FromMilliseconds(100)));
56+
57+
expected.Message.ShouldBe(WaitForStateHelper.TimeoutBeforePassMessage);
58+
}
59+
60+
[Fact(DisplayName = "WaitForState throws exception if statePredicate throws on a later render")]
61+
public void Test013()
62+
{
63+
const string expectedInnerMessage = "INNER MESSAGE";
64+
var cut = RenderComponent<TwoRendersTwoChanges>();
65+
cut.Find("#tick").Click();
66+
cut.Find("#tock").Click();
67+
68+
var expected = Should.Throw<WaitForFailedException>(() =>
69+
cut.WaitForState(() =>
70+
{
71+
if (cut.Find("#state").TextContent == "Stopped")
72+
throw new InvalidOperationException(expectedInnerMessage);
73+
return false;
74+
}));
75+
76+
expected.Message.ShouldBe(WaitForStateHelper.ExceptionInPredicateMessage);
77+
expected.InnerException.ShouldBeOfType<InvalidOperationException>()
78+
.Message.ShouldBe(expectedInnerMessage);
79+
}
80+
81+
[Fact(DisplayName = "WaitForState can wait for multiple renders and changes to occur")]
82+
public void Test100()
83+
{
84+
// Initial state is stopped
85+
var cut = RenderComponent<TwoRendersTwoChanges>();
86+
87+
// Clicking 'tick' changes the state, and starts a task
88+
cut.Find("#tick").Click();
89+
cut.Find("#state").TextContent.ShouldBe("Started");
90+
91+
// Clicking 'tock' completes the task, which updates the state
92+
// This click causes two renders, thus something is needed to await here.
93+
cut.Find("#tock").Click();
94+
cut.WaitForState(() =>
95+
{
96+
var elm = cut.Nodes.QuerySelector("#state");
97+
return elm?.TextContent == "Stopped";
98+
});
99+
}
100+
101+
[Fact(DisplayName = "WaitForState can detect async changes to properties in the CUT")]
102+
public void Test200()
103+
{
104+
var cut = RenderComponent<AsyncRenderChangesProperty>();
105+
cut.Instance.Counter.ShouldBe(0);
106+
107+
// Clicking 'tick' changes the counter, and starts a task
108+
cut.Find("#tick").Click();
109+
cut.Instance.Counter.ShouldBe(1);
110+
111+
// Clicking 'tock' completes the task, which updates the counter
112+
// This click causes two renders, thus something is needed to await here.
113+
cut.Find("#tock").Click();
114+
cut.WaitForState(() => cut.Instance.Counter == 2);
115+
116+
cut.Instance.Counter.ShouldBe(2);
117+
}
118+
119+
[Fact(DisplayName = "WaitForAssertion rethrows unhandled exception from a components async operation's methods")]
120+
public void Test300()
121+
{
122+
var cut = RenderComponent<ThrowsAfterAsyncOperation>();
123+
124+
Should.Throw<ThrowsAfterAsyncOperation.ThrowsAfterAsyncOperationException>(
125+
() => cut.WaitForAssertion(() => false.ShouldBeTrue()));
126+
}
127+
128+
[Fact(DisplayName = "WaitForState rethrows unhandled exception from components async operation's methods")]
129+
public void Test301()
130+
{
131+
var cut = RenderComponent<ThrowsAfterAsyncOperation>();
132+
133+
Should.Throw<ThrowsAfterAsyncOperation.ThrowsAfterAsyncOperationException>(
134+
() => cut.WaitForState(() => false));
135+
}
136+
137+
internal class ThrowsAfterAsyncOperation : ComponentBase
138+
{
139+
protected override async Task OnInitializedAsync()
140+
{
141+
await Task.Delay(1);
142+
await InvokeAsync(() => throw new ThrowsAfterAsyncOperationException());
143+
}
144+
145+
internal sealed class ThrowsAfterAsyncOperationException : Exception { }
146+
}
147+
}
148148
}

0 commit comments

Comments
 (0)