如何在单元测试中获取Windows Phone设备ID

Pav*_*hov 0 .net c# unit-testing windows-phone-8

如何在Windows Phone单元测试中获取设备ID?

我看了这个,但它对我不起作用.

在我的应用程序中,我正在使用这种方法,它适用于那种情况; 但是在单元测试中它不起作用,因为Exception失败:System.UnauthorizedAccessException:拒绝访问.

有什么想法吗?我的相关代码如下:

    private static string GetClientID() {
        string id = new Guid().ToString();
        object objUniqueID;
        if(DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out objUniqueID)) {
            return ConvertEx.HexStringEncode((byte[])objUniqueID);
        }
        else {
            return "Unknown";
        }
    }
Run Code Online (Sandbox Code Playgroud)

Tho*_*que 5

您甚至不应尝试在单元测试中获取设备ID,因为测试代码未在实际设备上运行.

相反,您应该使用封装设备ID检索的抽象,并为测试注入虚假实现.

例如,写一个这样的接口:

public interface IDeviceIdProvider
{
    string GetDeviceId();
}
Run Code Online (Sandbox Code Playgroud)

在您的应用程序中,实现DeviceIdProvider,如下所示:

class DeviceIdProvider : IDeviceIdProvider
{
    public string GetDeviceId()
    {
        object objUniqueID;
        if(DeviceExtendedProperties.TryGetValue("DeviceUniqueId", out objUniqueID)) {
            return ConvertEx.HexStringEncode((byte[])objUniqueID);
        }
        else {
            return "Unknown";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

IDeviceIdProvider通过将其传递给构造函数,使每个需要设备ID的类依赖:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

...

var foo = new Foo(new DeviceIdProvider());
Run Code Online (Sandbox Code Playgroud)

这称为依赖注入.您可以手动执行,也可以使用Unity,StructureMap,AutoFac,NInject等IoC容器.

在您的单元测试中,创建一个假实现:

class FakeDeviceIdProvider : IDeviceIdProvider
{
    private string _deviceId = Guid.NewGuid().ToString();
    public string GetDeviceId()
    {
        return _deviceId;
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其传递给您需要测试的类,例如Foo在上面的示例中:

[Test]
public void Foo_Should_Do_Something()
{
    var deviceIdProvider = new FakeDeviceIdProvider();
    var foo = new Foo(deviceIdProvider);
    // test the behavior of Foo...
}
Run Code Online (Sandbox Code Playgroud)

这允许您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...
}
Run Code Online (Sandbox Code Playgroud)