Skip to content

Commit 49ccd27

Browse files
committed
Upgrade to MSTest v4
1 parent 6e9ebb0 commit 49ccd27

24 files changed

Lines changed: 164 additions & 213 deletions

Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
<PackageVersion Include="Microsoft.SqlServer.DacFx" Version="170.2.70" />
4040
<PackageVersion Include="ModelContextProtocol.AspNetCore" Version="0.3.0-preview.3" />
4141
<PackageVersion Include="Moq" Version="4.20.72" />
42-
<PackageVersion Include="MSTest.TestAdapter" Version="3.8.3" />
43-
<PackageVersion Include="MSTest.TestFramework" Version="3.8.3" />
42+
<PackageVersion Include="MSTest.TestAdapter" Version="4.0.1" />
43+
<PackageVersion Include="MSTest.TestFramework" Version="4.0.1" />
4444
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
4545
<PackageVersion Include="Newtonsoft.Json.Schema" Version="4.0.1" />
4646
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />

src/Dibix.Testing.Generators/TestMethodGenerator.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Collections.Immutable;
43
using System.Linq;
54
using System.Threading;
65
using Dibix.Generators;
@@ -122,15 +121,15 @@ private readonly struct CodeGenerationTask
122121
public string? AssemblyName { get; }
123122
public string BaseTypeName { get; }
124123
public string BaseTypeNamespace { get; }
125-
public ImmutableArray<string> TypeNames { get; }
124+
public IReadOnlyCollection<string> TypeNames { get; }
126125

127126
public CodeGenerationTask(string? @namespace, string? assemblyName, string baseTypeName, string baseTypeNamespace, IEnumerable<string> typeNames)
128127
{
129128
this.Namespace = @namespace;
130129
this.AssemblyName = assemblyName;
131130
this.BaseTypeName = baseTypeName;
132131
this.BaseTypeNamespace = baseTypeNamespace;
133-
this.TypeNames = typeNames.ToImmutableArray();
132+
this.TypeNames = typeNames.ToArray();
134133
}
135134
}
136135
}

src/Dibix.Testing/Configuration/ConfigurationExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Collections;
2+
using System.Collections.Generic;
33
using Microsoft.VisualStudio.TestTools.UnitTesting;
44

55
namespace Microsoft.Extensions.Configuration
@@ -24,7 +24,7 @@ private sealed class RunSettingsConfigurationProvider : ConfigurationProvider
2424

2525
public override void Load()
2626
{
27-
foreach (DictionaryEntry entry in this._testContext.Properties)
27+
foreach (KeyValuePair<string, object> entry in this._testContext.Properties)
2828
{
2929
string value = entry.Value as string;
3030
if (String.IsNullOrEmpty(value))

src/Dibix.Testing/Configuration/TestConfigurationLoader.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,16 @@ private static bool TryGetProfileName(IConfiguration configuration, TestContext
8282
return true;
8383

8484
MethodInfo testMethod = TestImplementationResolver.ResolveTestMethod(testContext);
85+
if (testMethod == null)
86+
return false;
87+
8588
if (TryGetProfileName(testMethod, out profileName))
8689
return true;
8790

8891
Type testClass = testMethod.DeclaringType;
8992
if (TryGetProfileName(testClass, out profileName))
9093
return true;
9194

92-
profileName = null;
9395
return false;
9496
}
9597

src/Dibix.Testing/TestBase.cs

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public abstract class TestBase : ITestContextFacade, IDisposable
2525
private TestOutputWriter _testOutputHelper;
2626
private TestResultFileManager _testResultFileManager;
2727
private IDisposable _unhandledExceptionDiagnostics;
28+
internal const string AssemblyInitializeTestName = "[AssemblyInitialize]";
2829
#endregion
2930

3031
#region Properties
@@ -78,6 +79,10 @@ public async Task TestInitialize()
7879
{
7980
try
8081
{
82+
// Workaround since MSTest v4 upgrade
83+
testContext.Properties["FullyQualifiedTestClassName"] = typeof(T).FullName;
84+
testContext.Properties["TestName"] = AssemblyInitializeTestName;
85+
8186
using T instance = new T();
8287
instance.TestContext = testContext;
8388
instance.Scope = TestClassInstanceScope.AssemblyInitialize;
@@ -201,31 +206,6 @@ protected static TType AssertIsType<TType>(object instance) where TType : class
201206
Value: {instance}");
202207
}
203208

204-
protected static TException AssertThrows<TException>(Action action) where TException : Exception => AssertThrows<TException>(() =>
205-
{
206-
action();
207-
return Task.CompletedTask;
208-
}).Result;
209-
protected static async Task<TException> AssertThrows<TException>(Func<Task> action) where TException : Exception
210-
{
211-
Type expectedExceptionType = typeof(TException);
212-
try
213-
{
214-
await action().ConfigureAwait(false);
215-
}
216-
catch (TException exception)
217-
{
218-
return exception;
219-
}
220-
catch (Exception exception)
221-
{
222-
Type actualExceptionType = exception.GetType();
223-
throw new AssertFailedException($"Expected exception of type '{expectedExceptionType}' but an exception of '{actualExceptionType}' was thrown instead");
224-
}
225-
226-
throw new AssertFailedException($"Expected exception of type '{expectedExceptionType}' but none was thrown");
227-
}
228-
229209
protected static Task Retry(Func<CancellationToken, Task<bool>> retryMethod, CancellationToken cancellationToken = default) => retryMethod.Retry(cancellationToken);
230210
protected static Task Retry(Func<CancellationToken, Task<bool>> retryMethod, TimeSpan timeout, CancellationToken cancellationToken = default) => retryMethod.Retry(timeout, cancellationToken);
231211
protected static Task<TResult> Retry<TResult>(Func<CancellationToken, Task<TResult>> retryMethod, Func<TResult, bool> condition, CancellationToken cancellationToken = default) => retryMethod.Retry(condition, cancellationToken);

src/Dibix.Testing/Utilities/TestImplementationResolver.cs

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Concurrent;
3-
using System.Collections.Generic;
43
using System.Diagnostics;
54
using System.Linq;
65
using System.Reflection;
@@ -89,68 +88,11 @@ private static MethodInfo ResolveTestMethodFromTestContext(TestContext testConte
8988
throw new InvalidOperationException($"Could not resolve test class: {testClassName}");
9089

9190
string testMethodName = testContext.TestName;
92-
93-
if (testContext.ManagedMethod != null)
94-
{
95-
int startIndex = testContext.ManagedMethod.IndexOf('(');
96-
if (startIndex > 0)
97-
{
98-
// Data driven test
99-
int endIndex = testContext.ManagedMethod.IndexOf(')', startIndex);
100-
string parameters = testContext.ManagedMethod.Substring(startIndex + 1, endIndex - startIndex - 1);
101-
string[] parameterTypeNames = parameters.Split(',');
102-
103-
// We can't use Type.GetType here because the parameter type names are not assembly qualified
104-
//types = parameterTypeNames.Select(x => Type.GetType(x, throwOnError: true)).ToArray();
105-
MethodInfo dataDrivenTestMethod = ResolveDataDrivenTestMethod(testClass, testMethodName, parameterTypeNames);
106-
return dataDrivenTestMethod;
107-
}
108-
}
91+
if (testMethodName == TestBase.AssemblyInitializeTestName)
92+
return null;
10993

11094
MethodInfo testMethod = testClass.SafeGetMethod(testMethodName);
11195
return testMethod;
11296
}
113-
114-
private static MethodInfo ResolveDataDrivenTestMethod(Type type, string methodName, string[] parameterTypeNames)
115-
{
116-
const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public;
117-
118-
MethodInfo method = ResolveDataDrivenTestMethod(type, methodName, parameterTypeNames, bindingFlags);
119-
if (method == null)
120-
throw new InvalidOperationException($"Could not find method {type}.{methodName}({String.Join(", ", parameterTypeNames)}) [{bindingFlags}]");
121-
122-
return method;
123-
}
124-
private static MethodInfo ResolveDataDrivenTestMethod(IReflect type, string methodName, IReadOnlyList<string> parameterTypeNames, BindingFlags bindingFlags)
125-
{
126-
foreach (MethodInfo methodInfo in type.GetMethods(bindingFlags))
127-
{
128-
if (methodInfo.Name != methodName)
129-
continue;
130-
131-
ParameterInfo[] parameters = methodInfo.GetParameters();
132-
if (parameters.Length != parameterTypeNames.Count)
133-
continue;
134-
135-
bool parametersMatch = true;
136-
for (int i = 0; i < parameters.Length; i++)
137-
{
138-
string expectedParameterTypeName = parameterTypeNames[i];
139-
string actualParameterTypeName = parameters[i].ParameterType.FullName;
140-
if (expectedParameterTypeName == actualParameterTypeName)
141-
continue;
142-
143-
parametersMatch = false;
144-
break;
145-
}
146-
147-
if (!parametersMatch)
148-
continue;
149-
150-
return methodInfo;
151-
}
152-
153-
return null;
154-
}
15597
}
15698
}

src/Dibix.Testing/Utilities/TestMethodTestResultFileComposer.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,14 @@ private TestMethodTestResultFileComposer(string directory, string resultTestsDir
2424

2525
public static TestMethodTestResultFileComposer Create(TestContext testContext, string resultTestsDirectory)
2626
{
27-
string testName = testContext.TestDisplayName ?? testContext.TestName ?? throw new InvalidOperationException("TestDisplayName and TestName are null");
28-
string normalizedTestName = String.Join("_", testName.Split(Path.GetInvalidFileNameChars()));
29-
string testDirectory = Path.Combine(resultTestsDirectory, normalizedTestName);
30-
TestMethodTestResultFileComposer instance = new TestMethodTestResultFileComposer(testDirectory, resultTestsDirectory, normalizedTestName, testContext);
27+
string testName = testContext.TestDisplayName ?? testContext.TestName;
28+
string testDirectory = resultTestsDirectory;
29+
if (testName != TestBase.AssemblyInitializeTestName)
30+
{
31+
string normalizedTestName = String.Join("_", testName.Split(Path.GetInvalidFileNameChars()));
32+
testDirectory = Path.Combine(resultTestsDirectory, normalizedTestName);
33+
}
34+
TestMethodTestResultFileComposer instance = new TestMethodTestResultFileComposer(testDirectory, resultTestsDirectory, testName, testContext);
3135
return instance;
3236
}
3337

tests/Dibix.Dapper.Tests/DapperDatabaseAccessorAutoMultiMapTest.cs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ INNER JOIN (VALUES (N'agentdesk', N'desks')
2020
, (N'workingdesk', N'desks')) AS [y]([identifier], [identifier_parent]) ON [x].[identifier] = [y].[identifier_parent]";
2121
RecursiveEntity result = accessor.QuerySingle<RecursiveEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(RecursiveEntity), typeof(RecursiveEntity) }, "identifier");
2222
Assert.AreEqual("desks", result.Identifier);
23-
Assert.AreEqual(2, result.Children.Count);
23+
Assert.HasCount(2, result.Children);
2424
Assert.AreEqual("agentdesk", result.Children[0].Identifier);
2525
Assert.AreEqual("workingdesk", result.Children[1].Identifier);
2626
});
@@ -36,10 +36,10 @@ INNER JOIN (VALUES (N'dependentfeaturex', N'feature1')
3636
, (N'dependentfeaturey', N'feature1')) AS [z]([name], [name_feature]) ON [x].[name] = [z].[name_feature]";
3737
FeatureEntity result = accessor.QuerySingle<FeatureEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(FeatureEntity), typeof(FeatureItemEntity), typeof(DependentFeatureEntity) }, "name,name");
3838
Assert.AreEqual("feature1", result.Name);
39-
Assert.AreEqual(2, result.Items.Count);
39+
Assert.HasCount(2, result.Items);
4040
Assert.AreEqual("black", result.Items[0].Name);
4141
Assert.AreEqual("red", result.Items[1].Name);
42-
Assert.AreEqual(2, result.Dependencies.Count);
42+
Assert.HasCount(2, result.Dependencies);
4343
Assert.AreEqual("dependentfeaturex", result.Dependencies[0].Name);
4444
Assert.AreEqual("dependentfeaturey", result.Dependencies[1].Name);
4545
});
@@ -54,7 +54,7 @@ INNER JOIN (VALUES (N'black', N'feature1')
5454
, (N'red', N'feature1')) AS [z]([name], [name_feature]) ON [x].[name] = [z].[name_feature]";
5555
FeatureEntity result = accessor.QuerySingle<FeatureEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(FeatureEntity), typeof(FeatureBaseEntity), typeof(FeatureItemEntity) }, "name,name");
5656
Assert.AreEqual("feature1", result.Name);
57-
Assert.AreEqual(2, result.Items.Count);
57+
Assert.HasCount(2, result.Items);
5858
Assert.AreEqual("black", result.Items[0].Name);
5959
Assert.AreEqual("red", result.Items[1].Name);
6060
Assert.IsNotNull(result.Base);
@@ -76,20 +76,20 @@ INNER JOIN (VALUES (7, N'black_de', N'black')
7676
, (9, N'red_en', N'red')) AS [yt]([lcid], [value], [name_item]) ON [y].[name] = [yt].[name_item]";
7777
FeatureEntity result = accessor.QuerySingle<FeatureEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(FeatureEntity), typeof(TranslationEntity), typeof(FeatureItemEntity), typeof(TranslationEntity) }, "lcid,name,lcid");
7878
Assert.AreEqual("feature1", result.Name);
79-
Assert.AreEqual(2, result.Items.Count);
79+
Assert.HasCount(2, result.Items);
8080
Assert.AreEqual("black", result.Items[0].Name);
8181
Assert.AreEqual("red", result.Items[1].Name);
82-
Assert.AreEqual(2, result.Translations.Count);
82+
Assert.HasCount(2, result.Translations);
8383
Assert.AreEqual(7, result.Translations[0].Lcid);
8484
Assert.AreEqual("feature_de", result.Translations[0].Value);
8585
Assert.AreEqual(9, result.Translations[1].Lcid);
8686
Assert.AreEqual("feature_en", result.Translations[1].Value);
87-
Assert.AreEqual(2, result.Items[0].Translations.Count);
87+
Assert.HasCount(2, result.Items[0].Translations);
8888
Assert.AreEqual(7, result.Items[0].Translations[0].Lcid);
8989
Assert.AreEqual("black_de", result.Items[0].Translations[0].Value);
9090
Assert.AreEqual(9, result.Items[0].Translations[1].Lcid);
9191
Assert.AreEqual("black_en", result.Items[0].Translations[1].Value);
92-
Assert.AreEqual(2, result.Items[1].Translations.Count);
92+
Assert.HasCount(2, result.Items[1].Translations);
9393
Assert.AreEqual(7, result.Items[1].Translations[0].Lcid);
9494
Assert.AreEqual("red_de", result.Items[1].Translations[0].Value);
9595
Assert.AreEqual(9, result.Items[1].Translations[1].Lcid);
@@ -107,10 +107,10 @@ INNER JOIN (VALUES (0x1, N'feature1')
107107
, (0x2, N'feature1')) AS [z]([data], [feature]) ON [x].[name] = [z].[feature]";
108108
FeatureEntity result = accessor.QuerySingle<FeatureEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(FeatureEntity), typeof(FeatureItemEntity), typeof(byte[]) }, "name,data");
109109
Assert.AreEqual("feature1", result.Name);
110-
Assert.AreEqual(2, result.Items.Count);
110+
Assert.HasCount(2, result.Items);
111111
Assert.AreEqual("black", result.Items[0].Name);
112112
Assert.AreEqual("red", result.Items[1].Name);
113-
Assert.AreEqual(2, result.Pictures.Count);
113+
Assert.HasCount(2, result.Pictures);
114114
Assert.IsTrue(result.Pictures[0].SequenceEqual(Enumerable.Repeat((byte)1, 1)));
115115
Assert.IsTrue(result.Pictures[1].SequenceEqual(Enumerable.Repeat((byte)2, 1)));
116116
});
@@ -127,7 +127,7 @@ INNER JOIN (VALUES (N'feature1', N'product1')
127127
ProductEntity result = accessor.QuerySingle<ProductEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(ProductEntity), typeof(byte[]), typeof(FeatureEntity) }, "data,name");
128128
Assert.AreEqual("product1", result.Name);
129129
Assert.IsTrue(result.Picture.SequenceEqual(Enumerable.Repeat((byte)1, 1)));
130-
Assert.AreEqual(2, result.Features.Count);
130+
Assert.HasCount(2, result.Features);
131131
Assert.AreEqual("feature1", result.Features[0].Name);
132132
Assert.AreEqual("feature2", result.Features[1].Name);
133133
});
@@ -143,10 +143,10 @@ INNER JOIN (VALUES (N'/image1.png', N'feature1')
143143
, (N'/image2.png', N'feature1')) AS [z]([feature_imageurl], [feature_name]) ON [x].[feature_name] = [z].[feature_name]";
144144
FeatureEntity result = accessor.QuerySingle<FeatureEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(FeatureEntity), typeof(FeatureItemEntity), typeof(Uri) }, "name,feature_imageurl");
145145
Assert.AreEqual("feature1", result.Name);
146-
Assert.AreEqual(2, result.Items.Count);
146+
Assert.HasCount(2, result.Items);
147147
Assert.AreEqual("black", result.Items[0].Name);
148148
Assert.AreEqual("red", result.Items[1].Name);
149-
Assert.AreEqual(2, result.ImageUrls.Count);
149+
Assert.HasCount(2, result.ImageUrls);
150150
Assert.AreEqual("/image1.png", result.ImageUrls[0].ToString());
151151
Assert.AreEqual("/image2.png", result.ImageUrls[1].ToString());
152152
});
@@ -163,7 +163,7 @@ INNER JOIN (VALUES (N'feature1', N'product1')
163163
ProductEntity result = accessor.QuerySingle<ProductEntity>(commandText, CommandType.Text, accessor.Parameters().Build(), new[] { typeof(ProductEntity), typeof(int), typeof(FeatureEntity) }, "feature_id,name");
164164
Assert.AreEqual("product1", result.Name);
165165
Assert.AreEqual(0, result.FirstFeatureId); // Setting a primitive property using multi map doesn't make sense and is therefore not supported
166-
Assert.AreEqual(2, result.Features.Count);
166+
Assert.HasCount(2, result.Features);
167167
Assert.AreEqual("feature1", result.Features[0].Name);
168168
Assert.AreEqual("feature2", result.Features[1].Name);
169169
});

tests/Dibix.Dapper.Tests/DapperDatabaseAccessorRecursiveMapTest.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ public Task QuerySingle() => ExecuteTest(accessor =>
2121
Assert.IsNotNull(software);
2222
Assert.AreEqual(10, software.Id);
2323
Assert.AreEqual("Software", software.Name);
24-
Assert.AreEqual(null, software.ParentId);
25-
Assert.AreEqual(2, software.Categories.Count);
24+
Assert.IsNull(software.ParentId);
25+
Assert.HasCount(2, software.Categories);
2626
Assert.AreEqual(11, software.Categories[0].Id);
2727
Assert.AreEqual("Apple", software.Categories[0].Name);
2828
Assert.AreEqual(10, software.Categories[0].ParentId);
@@ -40,12 +40,12 @@ public Task GridResult_ReadMany() => ExecuteTest(accessor =>
4040
, (12, N'Microsoft', 10)) AS [x]([id], [name], [parentid])";
4141
using IMultipleResultReader reader = accessor.QueryMultiple(commandText, CommandType.Text, ParametersVisitor.Empty);
4242
IList<Category> categories = reader.ReadMany<Category>().ToArray();
43-
Assert.AreEqual(1, categories.Count);
43+
Assert.HasCount(1, categories);
4444
Assert.IsNotNull(categories[0]);
4545
Assert.AreEqual(10, categories[0].Id);
4646
Assert.AreEqual("Software", categories[0].Name);
47-
Assert.AreEqual(null, categories[0].ParentId);
48-
Assert.AreEqual(2, categories[0].Categories.Count);
47+
Assert.IsNull(categories[0].ParentId);
48+
Assert.HasCount(2, categories[0].Categories);
4949
Assert.AreEqual(11, categories[0].Categories[0].Id);
5050
Assert.AreEqual("Apple", categories[0].Categories[0].Name);
5151
Assert.AreEqual(10, categories[0].Categories[0].ParentId);

0 commit comments

Comments
 (0)