You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Today I tried to update my tests to the latest MSTest version. I followed the recommendations and replaced Assert.ThrowsException with Assert.ThrowsExactly with the replace function of the IDE (code fixes takes too long for all instances). These methods were implemented with #4257 and #4350.
Unfortunately, the migration led to a couple errors because the new ThrowsExactly methods don't have an Func<object?> overload, even though ThrowsException does. These errors are easy to fix but lead to worse code and more work.
To reproduce the problems I had, you can use this class.
public sealed class TestClass
{
private readonly bool _isInvalidState = true;
public TestClass(string text)
{
ArgumentNullException.ThrowIfNull(text);
}
public void ThrowOnInvalidState()
{
if (_isInvalidState)
{
throw new InvalidOperationException("Invalid state");
}
}
public string GetSomethingOThrowOnInvalidState()
{
if (_isInvalidState)
{
throw new InvalidOperationException("Invalid state");
}
return "Test";
}
public int this[int index]
{
get
{
ArgumentOutOfRangeException.ThrowIfLessThan(index, 0);
return 1;
}
}
}
Testing constructors leads to the Info CA1806:
[TestMethod]
public void Constructors_ThrowsException()
{
Assert.ThrowsException<ArgumentNullException>(() => new TestClass(null!));
}
[TestMethod]
public void Constructors_ThrowsExactly()
{
// Changing from ThrowsException to ThrowsExactly leads to Info CA1806:
// Test_ThrowsExactly creates a new instance of TestClass which is never used.
// Pass the instance as an argument to another method, assign the instance to a variable, or
// remove the object creation if it is unnecessary.
Assert.ThrowsExactly<ArgumentNullException>(() => new TestClass(null!));
// Possible fixes (worse code)
TestClass? tempInstance = null;
Assert.ThrowsExactly<ArgumentNullException>(() => tempInstance = new TestClass(null!));
Assert.ThrowsExactly<ArgumentNullException>(() => _ = new TestClass(null!));
}
Methods that don't have parameters and return something didn't require a lambda expression. For those cases, replacing ThrowsException with ThrowsExactly without any manual fixes leads to Error CS407:
[TestMethod]
public void ReturningMethodsWithoutParameters_ThrowsException()
{
TestClass instance = new TestClass("Test");
Assert.ThrowsException<InvalidOperationException>(instance.GetSomethingOThrowOnInvalidState);
}
[TestMethod]
public void ReturningMethodsWithoutParameters_ThrowsExactly()
{
TestClass instance = new TestClass("Test");
// Replacing ThrowsException with ThrowsExactly leads to Error CS407:
// 'string Tests.TestClass.GetSomethingOThrowOnInvalidState()' has the wrong return type
//Assert.ThrowsExactly<InvalidOperationException>(instance.GetSomethingOThrowOnInvalidState);
// Possible fix
Assert.ThrowsExactly<InvalidOperationException>(() => instance.GetSomethingOThrowOnInvalidState());
}
Indexers also can't be replaced without manual fixes:
[TestMethod]
public void Indexers_ThrowsException()
{
TestClass instance = new TestClass("Test");
Assert.ThrowsException<ArgumentOutOfRangeException>(() => instance[-1]);
}
[TestMethod]
public void Indexers_ThrowsExactly()
{
TestClass instance = new TestClass("Test");
// Replacing ThrowsException with ThrowsExactly leads to Error CS0201:
// Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
//Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => instance[-1]);
// Possible fixes (worse code)
int tempValue = 0;
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => tempValue = instance[-1]);
Assert.ThrowsExactly<ArgumentOutOfRangeException>(() => _ = instance[-1]);
}
A Func<object?> overload for the new ThrowsExactly and ThrowsExactlyAsync methods would be a good addition, would make the migration from ThrowsException easier and would improve the test code.
The text was updated successfully, but these errors were encountered:
Today I tried to update my tests to the latest MSTest version. I followed the recommendations and replaced
Assert.ThrowsException
withAssert.ThrowsExactly
with the replace function of the IDE (code fixes takes too long for all instances). These methods were implemented with #4257 and #4350.Unfortunately, the migration led to a couple errors because the new
ThrowsExactly
methods don't have anFunc<object?>
overload, even thoughThrowsException
does. These errors are easy to fix but lead to worse code and more work.To reproduce the problems I had, you can use this class.
Testing constructors leads to the Info CA1806:
Methods that don't have parameters and return something didn't require a lambda expression. For those cases, replacing
ThrowsException
withThrowsExactly
without any manual fixes leads to Error CS407:Indexers also can't be replaced without manual fixes:
A
Func<object?>
overload for the newThrowsExactly
andThrowsExactlyAsync
methods would be a good addition, would make the migration fromThrowsException
easier and would improve the test code.The text was updated successfully, but these errors were encountered: