如何使用 Moq 为异步函数抛出异常
How can I throw Exception for async function using Moq
我正在使用 xUnit 和 Moq 编写测试用例。
我在测试 class 中使用以下代码来测试另一个 class 方法的 catch()
private readonly IADLS_Operations _iADLS_Operations;
[Fact]
public void CreateCSVFile_Failure()
{
var dtData = new DataTable();
string fileName = "";
var mockClient = new Mock<IHttpHandler>();
this._iADLS_Operations = new ADLS_Operations(mockClient.Object);
mockClient.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest))); // here I want to return Exception instead of BadRequest. How to do that.
Exception ex = Assert.Throws<Exception>(() => this._iADLS_Operations.CreateCSVFile(dtData, fileName).Result);
Assert.Contains("Exception occurred while executing method:", ex.Message);
}
在下面的代码中,我想要 return 异常而不是 BadRequest
。
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
如何实现。
正如@Johnny 在评论中提到的,您可以将代码中的 Returns
替换为 Throws
,例如:
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Throws(new Exception("exception message"));
此外,您还可以抛出如下异常:
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Throws<InvalidOperationException>();
您可以找到有关抛出异常和最小起订量的更多信息 here。
考虑到被测代码的异步性,如果测试代码也是异步的会更好。最小起订量具有异步能力
[Fact]
public async Task CreateCSVFile_Failure() {
//Arrange
var dtData = new DataTable();
string fileName = "";
var mockClient = new Mock<IHttpHandler>();
this._iADLS_Operations = new ADLS_Operations(mockClient.Object);
mockClient
.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadRequest));
mockClient
.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.ThrowsAsync(new Exception("Some message here"));
//Act
Func<Task> act = () => this._iADLS_Operations.CreateCSVFile(dtData, fileName);
//Assert
Exception ex = await Assert.ThrowsAsync<Exception>(act);
Assert.Contains("Exception occurred while executing method:", ex.Message);
}
请注意在设置中使用 Moq 的 ReturnsAsync
和 ThrowsAsync
,以及 xUnit 的 Assert.ThrowsAsync
这现在可以让您避免像 .Result
这样可能导致死锁的阻塞调用。
我正在使用 xUnit 和 Moq 编写测试用例。
我在测试 class 中使用以下代码来测试另一个 class 方法的 catch()
private readonly IADLS_Operations _iADLS_Operations;
[Fact]
public void CreateCSVFile_Failure()
{
var dtData = new DataTable();
string fileName = "";
var mockClient = new Mock<IHttpHandler>();
this._iADLS_Operations = new ADLS_Operations(mockClient.Object);
mockClient.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest))); // here I want to return Exception instead of BadRequest. How to do that.
Exception ex = Assert.Throws<Exception>(() => this._iADLS_Operations.CreateCSVFile(dtData, fileName).Result);
Assert.Contains("Exception occurred while executing method:", ex.Message);
}
在下面的代码中,我想要 return 异常而不是 BadRequest
。
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.BadRequest)));
如何实现。
正如@Johnny 在评论中提到的,您可以将代码中的 Returns
替换为 Throws
,例如:
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Throws(new Exception("exception message"));
此外,您还可以抛出如下异常:
mockClient.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.Throws<InvalidOperationException>();
您可以找到有关抛出异常和最小起订量的更多信息 here。
考虑到被测代码的异步性,如果测试代码也是异步的会更好。最小起订量具有异步能力
[Fact]
public async Task CreateCSVFile_Failure() {
//Arrange
var dtData = new DataTable();
string fileName = "";
var mockClient = new Mock<IHttpHandler>();
this._iADLS_Operations = new ADLS_Operations(mockClient.Object);
mockClient
.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>(), It.IsAny<string>()))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadRequest));
mockClient
.Setup(repo => repo.SendAsync(It.IsAny<HttpRequestMessage>(), It.IsAny<string>()))
.ThrowsAsync(new Exception("Some message here"));
//Act
Func<Task> act = () => this._iADLS_Operations.CreateCSVFile(dtData, fileName);
//Assert
Exception ex = await Assert.ThrowsAsync<Exception>(act);
Assert.Contains("Exception occurred while executing method:", ex.Message);
}
请注意在设置中使用 Moq 的 ReturnsAsync
和 ThrowsAsync
,以及 xUnit 的 Assert.ThrowsAsync
这现在可以让您避免像 .Result
这样可能导致死锁的阻塞调用。