您甚至不應該在單元測試中嘗試獲取設備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容器,如統一,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
類的。
注意,代替手工創建一個假的實施IDeviceIdProvider
,你可以使用一個嘲弄的庫如FakeItEasy:
[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...
}