您甚至不应该尝试在单元测试中获取设备 ID,因为测试代码并未在实际设备上运行。
相反,您应该使用封装设备 ID 检索的抽象,并注入一个虚假的实现以进行测试。
例如,写一个这样的接口:
public interface IDeviceIdProvider
{
string GetDeviceId();
}
在您的应用程序中,像这样实现 DeviceIdProvider:
class DeviceIdProvider : IDeviceIdProvider
{
public string GetDeviceId()
{
object objUniqueID;
if(DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out objUniqueID)) {
return ConvertEx.HexStringEncode((byte[])objUniqueID);
}
else {
return "Unknown";
}
}
}
通过将其传递给构造函数,使每个需要设备 id 的类都依赖于IDeviceIdProvider:
class Foo
{
private readonly IDeviceIdProvider _deviceIdProvider;
public Foo(IDeviceIdProvider deviceIdProvider)
{
_deviceIdProvider = deviceIdProvider;
}
public void DoSomething()
{
string deviceId = _deviceIdProvider.GetDeviceId();
// do something with the device id
}
}
...
var foo = new Foo(new DeviceIdProvider());
这称为dependency injection。您可以手动完成,也可以使用 IoC 容器,例如 Unity、StructureMap、AutoFac、NInject 等。
在您的单元测试中,创建一个假实现:
class FakeDeviceIdProvider : IDeviceIdProvider
{
private string _deviceId = Guid.NewGuid().ToString();
public string GetDeviceId()
{
return _deviceId;
}
}
并将其传递给您需要测试的类,例如上例中的Foo:
[Test]
public void Foo_Should_Do_Something()
{
var deviceIdProvider = new FakeDeviceIdProvider();
var foo = new Foo(deviceIdProvider);
// test the behavior of Foo...
}
这允许您独立测试Foo,独立于真正的DeviceIdProvider 类。
请注意,您可以使用 FakeItEasy 等模拟库,而不是手动创建 IDeviceIdProvider 的虚假实现:
[Test]
public void Foo_Should_Do_Something()
{
var deviceIdProvider = A.Fake<IDeviceIdProvider>();
A.CallTo(() => deviceIdProvider.GetDeviceId()).Returns("123456");
var foo = new Foo(deviceIdProvider);
// test the behavior of Foo...
}