Moq 无法在单元测试中抛出异常
Moq fails to throw exception in Unit Test
我有一个 Azure 函数可以在 Azure Blob 存储中存储应用程序设置。为了对获取和添加设置的 class 进行单元测试,我使用 moq 让 blob 存储抽象 class (blobStorageRepository) 抛出异常。它主要有效。但是,我有两个测试失败了。
我有其他模拟 _blobStorageRepository 的单元测试。所有工作都很好,包括针对 "Get" 方法的测试正确抛出异常,但 "Add" 异常测试失败。我在下面包含了实际测试
Fact(DisplayName = "AddUserSettingsAsync - InvalidOperationException")]
[Trait("Category", "Unit Test")]
public async Task SettingsStoreAddUserSettingsTestWithException()
{
string userObject = Guid.NewGuid().ToString();
string correlationId = Guid.NewGuid().ToString();
string body = File.ReadAllText("TestData/userSettings.json");
UserSettingsObject userSettingsObject = JsonConvert.DeserializeObject<UserSettingsObject>(body);
var iFunctionEnvironment = TestHelpers.GetEnvironmentVariable("Test");
Uri.TryCreate("http://localhost", UriKind.Absolute, out Uri uri);
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(logger, correlationId, body, userObject))
.ThrowsAsync(new Exception("Function Add threw an exception"));
var iblobStorageRepository = iblobStorageRepositoryMoq.Object;
SettingsStore settingsStore = new SettingsStore(iFunctionEnvironment, iblobStorageRepository);
Exception exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await settingsStore.AddUserSettingsAsync(logger, correlationId, userSettingsObject, userObject));
Assert.Equal("Function Add threw an exception", exception.Message);
Assert.Null(exception.InnerException);
}
这是 blogStoreRepository 的接口:
Task<bool> Add(ILogger logger, string correlationId, string settingsObject, string settingsObjectName);
如有任何帮助,我们将不胜感激!
如果调用的模拟没有按预期运行,大多数情况下是因为设置与实际调用的不匹配。
考虑使用 It.IsAny<T>()
放宽预期
Fact(DisplayName = "AddUserSettingsAsync - InvalidOperationException")]
[Trait("Category", "Unit Test")]
public async Task SettingsStoreAddUserSettingsTestWithException() {
//Arrange
string userObject = Guid.NewGuid().ToString();
string correlationId = Guid.NewGuid().ToString();
string body = File.ReadAllText("TestData/userSettings.json");
UserSettingsObject userSettingsObject = JsonConvert.DeserializeObject<UserSettingsObject>(body);
var iFunctionEnvironment = TestHelpers.GetEnvironmentVariable("Test");
Uri.TryCreate("http://localhost", UriKind.Absolute, out Uri uri);
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(It.IsAny<ILogger>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ThrowsAsync(new InvalidOperationException("Function Add threw an exception"));
//The SUT
var subjectUnderTest = new SettingsStore(iFunctionEnvironment, iblobStorageRepositoryMoq.Object);
//Act
InvalidOperationException exception = await Assert.ThrowsAsync<InvalidOperationException>(() => subjectUnderTest.AddUserSettingsAsync(logger, correlationId, userSettingsObject, userObject));
//Assert
Assert.Equal("Function Add threw an exception", exception.Message);
Assert.Null(exception.InnerException);
}
注意设置的变化,如果断言 InvalidOperationException
被抛出,那么 mock 实际上应该抛出 InvalidOperationException
//...
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(It.IsAny<ILogger>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ThrowsAsync(new InvalidOperationException("Function Add threw an exception"));
//...
我有一个 Azure 函数可以在 Azure Blob 存储中存储应用程序设置。为了对获取和添加设置的 class 进行单元测试,我使用 moq 让 blob 存储抽象 class (blobStorageRepository) 抛出异常。它主要有效。但是,我有两个测试失败了。
我有其他模拟 _blobStorageRepository 的单元测试。所有工作都很好,包括针对 "Get" 方法的测试正确抛出异常,但 "Add" 异常测试失败。我在下面包含了实际测试
Fact(DisplayName = "AddUserSettingsAsync - InvalidOperationException")]
[Trait("Category", "Unit Test")]
public async Task SettingsStoreAddUserSettingsTestWithException()
{
string userObject = Guid.NewGuid().ToString();
string correlationId = Guid.NewGuid().ToString();
string body = File.ReadAllText("TestData/userSettings.json");
UserSettingsObject userSettingsObject = JsonConvert.DeserializeObject<UserSettingsObject>(body);
var iFunctionEnvironment = TestHelpers.GetEnvironmentVariable("Test");
Uri.TryCreate("http://localhost", UriKind.Absolute, out Uri uri);
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(logger, correlationId, body, userObject))
.ThrowsAsync(new Exception("Function Add threw an exception"));
var iblobStorageRepository = iblobStorageRepositoryMoq.Object;
SettingsStore settingsStore = new SettingsStore(iFunctionEnvironment, iblobStorageRepository);
Exception exception = await Assert.ThrowsAsync<InvalidOperationException>(async () => await settingsStore.AddUserSettingsAsync(logger, correlationId, userSettingsObject, userObject));
Assert.Equal("Function Add threw an exception", exception.Message);
Assert.Null(exception.InnerException);
}
这是 blogStoreRepository 的接口:
Task<bool> Add(ILogger logger, string correlationId, string settingsObject, string settingsObjectName);
如有任何帮助,我们将不胜感激!
如果调用的模拟没有按预期运行,大多数情况下是因为设置与实际调用的不匹配。
考虑使用 It.IsAny<T>()
Fact(DisplayName = "AddUserSettingsAsync - InvalidOperationException")]
[Trait("Category", "Unit Test")]
public async Task SettingsStoreAddUserSettingsTestWithException() {
//Arrange
string userObject = Guid.NewGuid().ToString();
string correlationId = Guid.NewGuid().ToString();
string body = File.ReadAllText("TestData/userSettings.json");
UserSettingsObject userSettingsObject = JsonConvert.DeserializeObject<UserSettingsObject>(body);
var iFunctionEnvironment = TestHelpers.GetEnvironmentVariable("Test");
Uri.TryCreate("http://localhost", UriKind.Absolute, out Uri uri);
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(It.IsAny<ILogger>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ThrowsAsync(new InvalidOperationException("Function Add threw an exception"));
//The SUT
var subjectUnderTest = new SettingsStore(iFunctionEnvironment, iblobStorageRepositoryMoq.Object);
//Act
InvalidOperationException exception = await Assert.ThrowsAsync<InvalidOperationException>(() => subjectUnderTest.AddUserSettingsAsync(logger, correlationId, userSettingsObject, userObject));
//Assert
Assert.Equal("Function Add threw an exception", exception.Message);
Assert.Null(exception.InnerException);
}
注意设置的变化,如果断言 InvalidOperationException
被抛出,那么 mock 实际上应该抛出 InvalidOperationException
//...
var iblobStorageRepositoryMoq = new Mock<IBlobStorageRepository>();
iblobStorageRepositoryMoq
.Setup(mock => mock.Add(It.IsAny<ILogger>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ThrowsAsync(new InvalidOperationException("Function Add threw an exception"));
//...