gpt4 book ai didi

c# - 对使用RegistryManager的类进行单元测试 C# Azure IoTHub

转载 作者:行者123 更新时间:2023-12-02 06:49:48 25 4
gpt4 key购买 nike

我正在尝试测试使用 RegistryManager 与 IoThub 通信的类。

我面临的问题是,在创建继承自 RegistryManager 的模拟类时,我能够重写除 ExportRegistryAsync 之外的所有方法。我在覆盖下看到一条红线,如果删除覆盖语句,我在构建项目时会收到​​此错误:

Error 4 'MockObjects.MockRegistryManager' does not implement inherited abstract member 'Microsoft.Azure.Devices.RegistryManager.ExportRegistryAsync(string, string)' Tests\MockObjects\MockRegistryManager.cs 9 18

代码:

public class MockRegistryManager : RegistryManager
{
private static List<Device> _devices;

public MockRegistryManager()
{
_devices = new List<Device>();
}

public override Task OpenAsync()
{
throw new NotImplementedException();
}


...


internal override Task ExportRegistryAsync(string storageAccountConnectionString, string containerName)
{
throw new NotImplementedException();
}

internal override Task ExportRegistryAsync(string storageAccountConnectionString, string containerName, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}

}

是否有更好的方法来测试使用 RegistryManager 的类?

任何帮助将不胜感激。

最佳答案

给定要测试的类的当前版本

public class Registry {
private readonly RegistryManager _registryManager;

public Registry(RegistryManager rm) {
_registryManager = rm;
}

public async Task<string> GetDeviceKey(string deviceId = null) {
if (deviceId == null) {
throw new Exception("Todo replace");
}
var device = await _registryManager.GetDeviceAsync(deviceId);
if (device == null) {
throw new Exception("TODO replace");
}
return device.Authentication.SymmetricKey.PrimaryKey;
}
}

如果您想对此进行测试,那么 RegistryManager 将会遇到问题。您需要对要使用的服务进行抽象,以便可以模拟/伪造它们进行测试,而无需使用真实的服务。

类似的东西

public interface IRegistryManager {
Task<Device> GetDeviceAsync(string deviceId);
}

这将允许您像这样重构您的类

public class Registry {
private readonly IRegistryManager _registryManager;

public Registry(IRegistryManager rm) {
_registryManager = rm;
}

public async Task<string> GetDeviceKey(string deviceId = null) {
if (deviceId == null) {
throw new Exception("Todo replace");
}
var device = await _registryManager.GetDeviceAsync(deviceId);
if (device == null) {
throw new Exception("TODO replace");
}
return device.Authentication.SymmetricKey.PrimaryKey;
}
}

现在允许您的 Registry 类完全可测试。您会注意到,除了注册表管理器字段的类型之外,不需要更改其他任何内容。不错。

您现在可以根据需要制作一个假的 RegistryManager 或使用测试框架进行模拟。

当您需要在生产代码中进行实际调用时,您只需将实际内容包装在界面中并将其传递到您的 Registry 类中

public class ActualRegistryManager : IRegistryManager {
private readonly RegistryManager _registryManager

public ActualRegistryManager (RegistryManager manager) {
_registryManager = manager;
}

public Task<Device> GetDeviceAsync(string deviceId) {
return _registryManager.GetDeviceAsync(deviceId);
}
}

这种方法的好处之一是,您现在只需向依赖类公开真正需要的功能。

使用 MoqFluentAssertions 我能够通过以下测试来模拟和测试 Registry

[TestMethod]
public async Task Registry_Should_Return_DeviceKey() {
//Arrange
var expectedPrimaryKey = Guid.NewGuid().ToString();
var deviceId = Guid.NewGuid().ToString();
var fakeDevice = new Device(deviceId) {
Authentication = new AuthenticationMechanism {
SymmetricKey = new SymmetricKey {
PrimaryKey = expectedPrimaryKey
}
}
};
var registryManagerMock = new Mock<IRegistryManager>();
registryManagerMock.Setup(m => m.GetDeviceAsync(deviceId))
.ReturnsAsync(fakeDevice);
var registry = new Registry(registryManagerMock.Object);

//Act
var deviceKey = await registry.GetDeviceKey(deviceId);

//Assert
deviceKey.Should().BeEquivalentTo(expectedPrimaryKey);
}

希望这有帮助。

关于c# - 对使用RegistryManager的类进行单元测试 C# Azure IoTHub,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36647213/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com