English 中文(简体)
为了测试目的,我怎么能模仿Iot HubserviceClient? (v2)
原标题:How can I mock IotHubServiceClient for testing purposes? (v2)

我有一个类别<代码>Iot Hubservice,该类别取决于C# IoT Hub SDK sIot HubserviceClient(SDK的五2版,目前正在审查之中),以对IoT/2007/5进行各种查询。 我试图通过撰写一些测试和模拟依赖物来提高我这一类人的可靠性:

[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);
}

然而,我无法在模拟伊特赫特·赫特·埃赫特时作出判断,在进行我的测试时会遇到以下错误:

System.NotSupportedException: Invalid setup on a non-virtual (overable in VB) member: mock => mock. 装置'

我的理解是,“DevicesClient”的基本原理是密封的,但我很想知道,是否有办法解决这一问题?

Edit: What my IotHubService class looks like:

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;
            }
        }
    }
问题回答

Using IotHubService with Azure IoT, I am able to mock and test.

  • Sample example with mock test and unit test.
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();
}

Output: enter image description here

With Mocking and Testing:

 [Fact]
    public async Task CheckDeviceConnection_DeviceExists_ReturnsTrue()
    {
        // Arrange
        var deviceId = "mytestdevice1";
        var mockRegistryManager = new Mock<RegistryManager>();
        mockRegistryManager.Setup(manager => manager.GetDeviceAsync(deviceId))
                           .ReturnsAsync(new Device(deviceId));

        var iotHubService = new IotHubService(ConnectionString, mockRegistryManager.Object);

        // Act
        Device device = await iotHubService.GetDeviceByIdAsync(deviceId);

        // Assert
        Assert.NotNull(device);
        Assert.Equal(deviceId, device.Id);
        Assert.True(device.ConnectionState == DeviceConnectionState.Connected);

        // Print the result of this test
        if (device != null && device.ConnectionState == DeviceConnectionState.Connected)
        {
            Console.WriteLine("CheckDeviceConnection_DeviceExists_ReturnsTrue: Passed");
        }
        else
        {
            Console.WriteLine("CheckDeviceConnection_DeviceExists_ReturnsTrue: Failed");
        }
    }




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签