如何在单元测试中获取windows phone设备ID

How to get windows phone device ID in unit test

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

我读了 this,但它对我不起作用。

在我的应用程序中,我使用了这种方法,在那种情况下它是有效的;但在单元测试中它不起作用,失败并显示 Exception: System.UnauthorizedAccessException: Access is denied.

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

    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";
        }
    }

您甚至不应该尝试在单元测试中获取设备 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 的 class 都依赖于 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;
    }
}

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

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

这允许您单独测试 Foo,独立于真实的 DeviceIdProvider class。

请注意,您可以使用模拟库,例如 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...
}