我正在为源代码提供单元测试,但是我在这里犯了一个错误。 如果该值确实为“ null”,那我该怎么办? 那有可能吗?
我试图弄清楚其他人如何解决它,但是在下面的线程中,我不太了解。 C# in my unit test i want to see if it is null or an empty string
->如果像上面的示例中那样使用IsNullOrEmpty(),那么在我的代码段中是什么样子?
这是我的单元测试中的受影响区域:
Assert.That(deviceInfo.SerialNumber == null);
出现以下错误消息:
消息:System.ArgumentNullException:值不能为null。参数名称:来源
编辑-这是我的环境:
这是带有DeviceDetails对象的类,该类在主体中具有所有信息。
public virtual IActionResult DevicesIdGet([FromRoute][Required]string id)
{
var device = _deviceManager.GetDevice(id);
if (device == null)
return NotFound();
var deviceDetails = new DeviceDetails
{
IsOnline = device.IsOnline(),
SerialNumber = null
};
return Ok(deviceDetails);
}
单元测试
private Device _testDevice;
[SetUp]
public void SetUp()
{
_testDevice = new Device
{
Id = 1,
DeviceType = 1,
DisplayName = "TestDevice",
IpAddress = IPAddress.Parse("127.0.0.1"),
IpAddressString = "127.0.0.1"
};
}
[Test]
public void If_DeviceIsAvailable_Then_DeviceIdIsSelected()
{
// ARRANGE
var deviceManagerMock = new Mock<IDeviceManager>();
deviceManagerMock.Setup(manager => manager.GetDevices(false))
.Returns(new List<Device>
{
_testDevice
})
.Verifiable();
var subject = new DevicesApiController(deviceManagerMock.Object);
// ACT
var result = subject.DevicesIdGet("1");
// ASSERT
var deviceInfos = result as IEnumerable<DeviceDetails>;
var deviceInfo = deviceInfos.Single();
Assert.That(deviceInfo.IsOnline == true);
Assert.That(deviceInfo.SerialNumber == null);
}
答案 0 :(得分:3)
您的控制器调用了IDeviceManager
的此方法,该方法没有被模拟 :
var device = _deviceManager.GetDevice(id);
不嘲笑该方法是导致异常的原因之一。但是,如果您对其进行修复并模拟该方法(使用Setup
在模拟中指定结果),则仍然会遇到相同的异常。以后再说。首先,这是您的代码崩溃的路径:
由于未对它进行模拟,因此在模拟中调用GetDevice
的返回值将为null,因此发生这种情况:
if (device == null)
return NotFound();
该方法的结果为NotFound
结果。
然后,这在单元测试中发生:
var deviceInfos = result as IEnumerable<DeviceDetails>;
var deviceInfo = deviceInfos.Single();
result
是NotFoundResult
。 result as IEnumerable<DeviceDetails>
返回null
。
因此,您实际上正在这样做:
IEnumerable<DeviceDetails> deviceInfos = null;
var deviceInfo = deviceInfos.Single();
传递给source
方法的Single
参数为null,因此是异常。
如果嘲笑GetDevice
,出于几乎完全相同的原因,您仍然会收到相同的错误。现在,您的代码将返回OkObjectResult
而不是NotFoundResult
。您将尝试将其强制转换为IEnumerable<DeviceDetails>
,但仍将是null
,并且会遇到相同的异常。
您需要的是从OkObjectResult
获取值,就像这样:
var actionResult = subject.DevicesIdGet("1") as OkObjectResult;
var deviceInfos = actionResult.Value as IEnumerable<DeviceDetails> ;
var deviceInfo = deviceInfos.Single();
答案 1 :(得分:0)
根据发布的代码,似乎deviceInfo可以为null。您可以执行以下操作:
if (deviceInfo == null)
throw new ArgumentNullException(“source”);
// rest of the code
答案 2 :(得分:0)
当您具有null值时,应引发异常。
如果您已经这样做,则是另一行引发此错误。