I am using ReSharper 2024.2 and still I get the suggestion that I should not be using the following code:
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse
{
ArgumentNullException.ThrowIfNullOrEmpty(query);
ArgumentNullException.ThrowIfNullOrWhiteSpace(query);
ArgumentNullException.ThrowIfNull(Logger);
Instead it suggests I use
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse
{
ArgumentException.ThrowIfNullOrEmpty(query);
ArgumentException.ThrowIfNullOrWhiteSpace(query);
ArgumentNullException.ThrowIfNull(Logger);
Or
public async Task<T> GetQueryAsync<T>(string query, bool isToBeValidated = true) where T : IEndPointResponse
{
if (string.IsNullOrEmpty(query) || string.IsNullOrWhiteSpace(query)) throw new ArgumentNullException(nameof(query));
The issue is that the calling the derived class method ArgumentException.ThrowIfNullOrEmpty() will return an ArgumentException!
Here's an example demonstrating my issue
[TestFixture]
public class Tests
{
readonly MyClass _testClass = new();
#region Passes due to null being passed in and ArgumentNullException being thrown
[Test]
public void Test_MyMethod_Passes()
{
Assert.Throws<ArgumentNullException>(() =>
{
_ = _testClass.Method(null); // passes with ArgumentNullException
});
}
[Test]
public void Test_MyMethodAsync_Passes()
{
Assert.ThrowsAsync<ArgumentNullException>(async () => await _testClass.MethodAsync(null).ToListAsync()); // passes with ArgumentNullException
}
#endregion
#region Fails with ArgumentException being returned instead of ArgumentNullException
[TestCase("")]
[TestCase(" ")]
public void Test_MyMethod(string someText)
{
Assert.Throws<ArgumentNullException>(() => _testClass.Method(someText)); // fails with ArgumentException not ArgumentNullException
}
[TestCase("")]
[TestCase(" ")]
public void Test_MyMethodAsync_Fails(string someText)
{
Assert.ThrowsAsync<ArgumentNullException>(async () => await _testClass.MethodAsync(someText).ToListAsync()); // fails with ArgumentException not ArgumentNullException
}
#endregion
}
public class MyClass
{
public List<string> Method(string? someText)
{
ArgumentNullException.ThrowIfNull(someText);
ArgumentException.ThrowIfNullOrEmpty(someText);
ArgumentException.ThrowIfNullOrWhiteSpace(someText);
var result = new List<string> { "Document1", "Document2" };
return result;
}
public async IAsyncEnumerable<string> MethodAsync(string? someText)
{
ArgumentNullException.ThrowIfNull(someText);
ArgumentException.ThrowIfNullOrEmpty(someText);
ArgumentException.ThrowIfNullOrWhiteSpace(someText);
// Simulate async data fetching
await Task.Delay(100);
yield return "Document1";
yield return "Document2";
}
}
TL;DR
If I want ArgumentNullException, I have to use ArgumentNulLException.ThrowIfNullOrEmpty(someText) otherwise I get ArgumentException.
ArgumentException.ThrowIfNullOrEmptywon't throw an ArgumentNullException? Just because it's declared inArgumentExceptiondoesn't mean that's what it will throw. Did you try running your tests after applying the ReSharper suggestion?ArgumentExceptionis a coincidence.