我有一个类
IotHubService
,它依赖于 C# IoTHub SDK 的 IotHubServiceClient
(SDK 的 v2 版本,当前处于预览版)来在 IoTHub 上执行各种查询。我试图通过编写一些测试和模拟依赖关系来提高班级的可靠性:
[Fact]
public async Task GetDeviceByIdAsync_ValidDeviceId_ReturnsDevice()
{
// Arrange
string deviceId = "testDeviceId";
Device expectedDevice = new Device(deviceId);
// Create a mock IotHubServiceClient
Mock<IotHubServiceClient> mockIotHubServiceClient = new Mock<IotHubServiceClient>();
mockIotHubServiceClient
.Setup(c => c.Devices.GetAsync(It.IsAny<string>(), It.IsAny<CancellationToken>()))
.ReturnsAsync(expectedDevice);
// Create an instance of IoTHubService using the mock client
IotHubService ioTHubService = new IotHubService(mockIotHubServiceClient.Object);
// Act
Device result = await ioTHubService.GetDeviceByIdAsync(deviceId);
// Assert
Assert.Equal(expectedDevice, result);
mockIotHubServiceClient.Verify(c => c.Devices.GetAsync(deviceId, default(CancellationToken)), Times.Once);
}
但是,我没有成功模拟 IotHubServiceClient 并在运行测试时收到以下错误:
System.NotSupportedException:非虚拟(可在 VB 中重写)成员上的设置无效:mock => mock.Devices`
我知道底层
DevicesClient
是密封的,但我想知道是否有办法解决这个问题?
编辑:我的
IotHubService
课程是什么样的:
public class IotHubService : IIotHubService
{
protected readonly IotHubServiceClient _iotHubServiceClient;
public IotHubService(string connectionString)
{
_iotHubServiceClient = new IotHubServiceClient(connectionString);
}
public IotHubService(IotHubServiceClient iotHubServiceClient)
{
_iotHubServiceClient = iotHubServiceClient;
}
public async Task<Device> GetDeviceByIdAsync(string deviceId)
{
if (string.IsNullOrEmpty(deviceId))
{
throw new ArgumentNullException(nameof(deviceId));
}
try
{
return await _iotHubServiceClient.Devices.GetAsync(deviceId);
}
catch (Exception)
{
throw;
}
}
}
将
IotHubService
与 Azure IoT 结合使用,我能够进行模拟和测试。
public class IotHubServiceTests
{
private const string ConnectionString = " ";
[Fact]
public async Task CheckDeviceConnection_DeviceExists_ReturnsTrue()
{
var iotHubService = new IotHubService(ConnectionString);
var deviceId = " ";
Device device = await iotHubService.GetDeviceByIdAsync(deviceId);
Assert.NotNull(device);
Assert.Equal(deviceId, device.Id);
Assert.True(device.ConnectionState == DeviceConnectionState.Connected);
if (device != null && device.ConnectionState == DeviceConnectionState.Connected)
{
Console.WriteLine("CheckDeviceConnection_DeviceExists_ReturnsTrue: Passed");
}
else
{
Console.WriteLine("CheckDeviceConnection_DeviceExists_ReturnsTrue: Failed");
}
}
[Fact]
public async Task CheckDeviceConnection_DeviceNotFound_ReturnsFalse()
{
var iotHubService = new IotHubService(ConnectionString);
var deviceId = "nonexistent_device";
Device device = await iotHubService.GetDeviceByIdAsync(deviceId);
Assert.Null(device);
if (device == null)
{
Console.WriteLine("CheckDeviceConnection_DeviceNotFound_ReturnsFalse: Passed");
}
else
{
Console.WriteLine("CheckDeviceConnection_DeviceNotFound_ReturnsFalse: Failed");
}
}
[Fact]
public async Task CheckDeviceConnection_NullDeviceId_ThrowsArgumentNullException()
{
var iotHubService = new IotHubService(ConnectionString);
string deviceId = null;
await Assert.ThrowsAsync<ArgumentNullException>(() => iotHubService.GetDeviceByIdAsync(deviceId));
Console.WriteLine("CheckDeviceConnection_NullDeviceId_ThrowsArgumentNullException: Passed");
}
}
public class IotHubService
{
private readonly RegistryManager _registryManager;
public IotHubService(string connectionString)
{
_registryManager = RegistryManager.CreateFromConnectionString(connectionString);
}
public async Task<Device> GetDeviceByIdAsync(string deviceId)
{
if (string.IsNullOrEmpty(deviceId))
{
throw new ArgumentNullException(nameof(deviceId));
}
try
{
return await _registryManager.GetDeviceAsync(deviceId);
}
catch (DeviceNotFoundException)
{
return null;
}
catch (Exception ex)
{
throw ex;
}
}
}
static void Main(string[] args)
{
Console.WriteLine("Running Xunit tests...");
var assembly = typeof(Program).Assembly;
var assemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location;
var result = Xunit.ConsoleClient.Program.Main(new[] { assemblyLocation });
if (result == 0)
{
Console.WriteLine("Xunit tests passed.");
}
else
{
Console.WriteLine("Xunit tests failed.");
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
输出: