-
-
Notifications
You must be signed in to change notification settings - Fork 129
Expand file tree
/
Copy pathContextProviderTests.cs
More file actions
76 lines (67 loc) · 2.95 KB
/
Copy pathContextProviderTests.cs
File metadata and controls
76 lines (67 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
namespace TUnit.UnitTests;
/// <summary>
/// Regression tests for https://github.com/thomhurst/TUnit/issues/6180 —
/// a partially-built <see cref="TestContext"/> (with <c>TestDetails == null</c>) must never
/// be observable via <see cref="ClassHookContext.Tests"/>, otherwise AfterEvery(Class) hooks
/// running concurrently with dynamic test registration NRE on <c>test.Metadata.TestDetails</c>.
/// </summary>
public class ContextProviderTests
{
[Test]
public async Task CreateTestContext_PublishesContextWithTestDetailsAlreadyAssigned()
{
var provider = new ContextProvider(new EmptyServiceProvider(), Guid.NewGuid().ToString(), testFilter: null);
var classMetadata = new ClassMetadata
{
Type = typeof(DummyTestClass),
TypeInfo = new ConcreteType(typeof(DummyTestClass)),
Name = nameof(DummyTestClass),
Namespace = typeof(DummyTestClass).Namespace ?? string.Empty,
Assembly = new AssemblyMetadata
{
Name = typeof(DummyTestClass).Assembly.GetName().Name ?? string.Empty
},
Parent = null,
Parameters = [],
Properties = []
};
var methodMetadata = MethodMetadataFactory.Create(
nameof(DummyTestClass.SomeTest),
typeof(DummyTestClass),
typeof(Task),
classMetadata);
var testDetails = new TestDetails([])
{
TestId = "Test:0",
TestName = nameof(DummyTestClass.SomeTest),
ClassType = typeof(DummyTestClass),
MethodName = nameof(DummyTestClass.SomeTest),
ClassInstance = PlaceholderInstance.Instance,
TestMethodArguments = [],
TestClassArguments = [],
MethodMetadata = methodMetadata,
ReturnType = typeof(Task),
AttributesByType = new Dictionary<Type, IReadOnlyList<Attribute>>()
};
var context = provider.CreateTestContext(
typeof(DummyTestClass),
new TestBuilderContext { TestMetadata = methodMetadata },
testDetails,
CancellationToken.None);
var classContext = provider.GetOrCreateClassContext(typeof(DummyTestClass));
var publishedContext = classContext.Tests.Single();
// The contract callers (and AfterEvery(Class) hooks) rely on: by the time a context is
// visible in ClassHookContext.Tests, its TestDetails is set — no post-hoc assignment.
await Assert.That(publishedContext).IsSameReferenceAs(context);
await Assert.That(publishedContext.TestDetails).IsNotNull();
await Assert.That(publishedContext.Metadata.TestDetails).IsSameReferenceAs(testDetails);
}
private sealed class DummyTestClass
{
public Task SomeTest() => Task.CompletedTask;
}
private sealed class EmptyServiceProvider : IServiceProvider
{
public object? GetService(Type serviceType) => null;
}
}