Window Phone 的 TestAccelerometer 实现
TestAccelerometer implementation for Window Phone
问题
我的应用程序通过 Microsoft.Devices.Sensors.Accelerometer
class
使用加速度计数据
现在我想编写 Unit 或 CodedUI 测试,因此我需要有一个特殊的测试实现 Accelerometer
来控制返回的数据
理论上我有3个选择:
- 创建
Accelerometer
的子 class - 不可能,因为 Accelerometer
是 sealed
class
- 通过在 run-time 处使用反射替换
Accelerometer
的实现 - 恕我直言,这不是最佳选择
- 创建
SensorBase<AccelerometerReading>
的子class - 不错的选择
我决定按照 #1
并将我的 TestAccelerometer
实施为 SensorBase<AccelerometerReading>
child
这是我的问题:
`Error CS1729 'SensorBase<AccelerometerReading>' does not contain a constructor that takes 0 arguments`
错误很明显我查看了反编译代码(JetBrains dotPeak
工具),但根本没有找到任何构造函数。
问题
如何找到合适的构造函数用于我的 TestAccelerometer
实现?
反编译代码
Microsoft.Devices.Sensors.Accelerometer
// Type: Microsoft.Devices.Sensors.Accelerometer
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// Provides Windows Phone applications access to the device’s accelerometer sensor.
/// </summary>
public sealed class Accelerometer : SensorBase<AccelerometerReading>
{
/// <summary>
/// Gets or sets whether the device on which the application is running supports the accelerometer sensor.
/// </summary>
///
/// <returns>
/// true if the device on which the application is running supports the accelerometer sensor; otherwise, false.
/// </returns>
public static bool IsSupported { get; internal set; }
/// <summary>
/// Gets the current state of the accelerometer. The value is a member of the <see cref="T:Microsoft.Devices.Sensors.SensorState"/> enumeration.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:Microsoft.Devices.Sensors.SensorState"/>.
/// </returns>
public SensorState State { get; private set; }
/// <summary>
/// Occurs when new data arrives from the accelerometer. This method is deprecated in the current release. Applications should use the <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> event of the <see cref="T:Microsoft.Devices.Sensors.SensorBase`1"/> class instead.
/// </summary>
[Obsolete("use CurrentValueChanged")]
public event EventHandler<AccelerometerReadingEventArgs> ReadingChanged;
static Accelerometer();
/// <summary>
/// Releases the managed and unmanaged resources used by the <see cref="T:Microsoft.Devices.Sensors.Accelerometer"/>.
/// </summary>
public new void Dispose();
/// <summary>
/// Starts data acquisition from the accelerometer.
/// </summary>
public new void Start();
/// <summary>
/// Stops data acquisition from the accelerometer.
/// </summary>
public new void Stop();
}
}
Microsoft.Devices.Sensors.SensorBase
// Type: Microsoft.Devices.Sensors.SensorBase`1
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
using System.Security;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// The base class for all Windows Phone sensor classes.
/// </summary>
/// <typeparam name="TSensorReading">The type of reading returned by the sensor.</typeparam>
public abstract class SensorBase<TSensorReading> : IDisposable where TSensorReading : ISensorReading
{
/// <summary>
/// Gets an object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor. This object will be one of the following types, depending on which sensor is being referenced: <see cref="T:Microsoft.Devices.Sensors.AccelerometerReading"/>, <see cref="T:Microsoft.Devices.Sensors.CompassReading"/>, <see cref="T:Microsoft.Devices.Sensors.GyroscopeReading"/>, <see cref="T:Microsoft.Devices.Sensors.MotionReading"/>.
/// </summary>
///
/// <returns>
/// An object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor.
/// </returns>
public TSensorReading CurrentValue { get; }
/// <summary>
/// Gets or sets the preferred time between <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> events.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.TimeSpan"/>. The preferred time between CurrentValueChanged events.
/// </returns>
public TimeSpan TimeBetweenUpdates { get; set; }
/// <summary>
/// Gets the validity of the sensor’s data.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.Boolean"/>. true if the sensor’s data is valid; otherwise, false.
/// </returns>
public bool IsDataValid { get; }
/// <summary>
/// Occurs when new data arrives from the sensor.
/// </summary>
public event EventHandler<SensorReadingEventArgs<TSensorReading>> CurrentValueChanged;
static SensorBase();
internal SensorBase();
/// <summary>
/// Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection.
/// </summary>
[SecuritySafeCritical]
~SensorBase();
/// <summary>
/// Releases the managed and unmanaged resources used by the sensor.
/// </summary>
[SecuritySafeCritical]
public void Dispose();
/// <summary>
/// Starts acquisition of data from the sensor.
/// </summary>
public virtual void Start();
/// <summary>
/// Stops acquisition of data from the sensor.
/// </summary>
public virtual void Stop();
}
}
你找到了构造函数:
internal SensorBase();
此构造函数阻止 SensorBase
具有默认的 public 构造函数,并且此 class 无法从其程序集外部进行子class。
测试它会很复杂。您可以重新设计应用程序并使用 wrapper/adapter 作为 Accelerometer
仅用于测试目的,或者您可以检查 Windows [=25= 上是否存在 mocking a sealed class 的可能性].
问题
我的应用程序通过 Microsoft.Devices.Sensors.Accelerometer
class
现在我想编写 Unit 或 CodedUI 测试,因此我需要有一个特殊的测试实现 Accelerometer
来控制返回的数据
理论上我有3个选择:
- 创建
Accelerometer
的子 class - 不可能,因为Accelerometer
是sealed
class - 通过在 run-time 处使用反射替换
Accelerometer
的实现 - 恕我直言,这不是最佳选择 - 创建
SensorBase<AccelerometerReading>
的子class - 不错的选择
我决定按照 #1
并将我的 TestAccelerometer
实施为 SensorBase<AccelerometerReading>
child
这是我的问题:
`Error CS1729 'SensorBase<AccelerometerReading>' does not contain a constructor that takes 0 arguments`
错误很明显我查看了反编译代码(JetBrains dotPeak
工具),但根本没有找到任何构造函数。
问题
如何找到合适的构造函数用于我的 TestAccelerometer
实现?
反编译代码
Microsoft.Devices.Sensors.Accelerometer
// Type: Microsoft.Devices.Sensors.Accelerometer
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// Provides Windows Phone applications access to the device’s accelerometer sensor.
/// </summary>
public sealed class Accelerometer : SensorBase<AccelerometerReading>
{
/// <summary>
/// Gets or sets whether the device on which the application is running supports the accelerometer sensor.
/// </summary>
///
/// <returns>
/// true if the device on which the application is running supports the accelerometer sensor; otherwise, false.
/// </returns>
public static bool IsSupported { get; internal set; }
/// <summary>
/// Gets the current state of the accelerometer. The value is a member of the <see cref="T:Microsoft.Devices.Sensors.SensorState"/> enumeration.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:Microsoft.Devices.Sensors.SensorState"/>.
/// </returns>
public SensorState State { get; private set; }
/// <summary>
/// Occurs when new data arrives from the accelerometer. This method is deprecated in the current release. Applications should use the <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> event of the <see cref="T:Microsoft.Devices.Sensors.SensorBase`1"/> class instead.
/// </summary>
[Obsolete("use CurrentValueChanged")]
public event EventHandler<AccelerometerReadingEventArgs> ReadingChanged;
static Accelerometer();
/// <summary>
/// Releases the managed and unmanaged resources used by the <see cref="T:Microsoft.Devices.Sensors.Accelerometer"/>.
/// </summary>
public new void Dispose();
/// <summary>
/// Starts data acquisition from the accelerometer.
/// </summary>
public new void Start();
/// <summary>
/// Stops data acquisition from the accelerometer.
/// </summary>
public new void Stop();
}
}
Microsoft.Devices.Sensors.SensorBase
// Type: Microsoft.Devices.Sensors.SensorBase`1
// Assembly: Microsoft.Devices.Sensors, Version=8.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e
// MVID: 81ED89AA-6B11-4B39-BAFA-38D59CBB1E3B
// Assembly location: C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\WindowsPhone\v8.0\Microsoft.Devices.Sensors.dll
using System;
using System.Security;
namespace Microsoft.Devices.Sensors
{
/// <summary>
/// The base class for all Windows Phone sensor classes.
/// </summary>
/// <typeparam name="TSensorReading">The type of reading returned by the sensor.</typeparam>
public abstract class SensorBase<TSensorReading> : IDisposable where TSensorReading : ISensorReading
{
/// <summary>
/// Gets an object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor. This object will be one of the following types, depending on which sensor is being referenced: <see cref="T:Microsoft.Devices.Sensors.AccelerometerReading"/>, <see cref="T:Microsoft.Devices.Sensors.CompassReading"/>, <see cref="T:Microsoft.Devices.Sensors.GyroscopeReading"/>, <see cref="T:Microsoft.Devices.Sensors.MotionReading"/>.
/// </summary>
///
/// <returns>
/// An object that implements <see cref="T:Microsoft.Devices.Sensors.ISensorReading"/> that contains the current value of the sensor.
/// </returns>
public TSensorReading CurrentValue { get; }
/// <summary>
/// Gets or sets the preferred time between <see cref="E:Microsoft.Devices.Sensors.SensorBase`1.CurrentValueChanged"/> events.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.TimeSpan"/>. The preferred time between CurrentValueChanged events.
/// </returns>
public TimeSpan TimeBetweenUpdates { get; set; }
/// <summary>
/// Gets the validity of the sensor’s data.
/// </summary>
///
/// <returns>
/// Type: <see cref="T:System.Boolean"/>. true if the sensor’s data is valid; otherwise, false.
/// </returns>
public bool IsDataValid { get; }
/// <summary>
/// Occurs when new data arrives from the sensor.
/// </summary>
public event EventHandler<SensorReadingEventArgs<TSensorReading>> CurrentValueChanged;
static SensorBase();
internal SensorBase();
/// <summary>
/// Allows an object to try to free resources and perform other cleanup operations before the Object is reclaimed by garbage collection.
/// </summary>
[SecuritySafeCritical]
~SensorBase();
/// <summary>
/// Releases the managed and unmanaged resources used by the sensor.
/// </summary>
[SecuritySafeCritical]
public void Dispose();
/// <summary>
/// Starts acquisition of data from the sensor.
/// </summary>
public virtual void Start();
/// <summary>
/// Stops acquisition of data from the sensor.
/// </summary>
public virtual void Stop();
}
}
你找到了构造函数:
internal SensorBase();
此构造函数阻止 SensorBase
具有默认的 public 构造函数,并且此 class 无法从其程序集外部进行子class。
测试它会很复杂。您可以重新设计应用程序并使用 wrapper/adapter 作为 Accelerometer
仅用于测试目的,或者您可以检查 Windows [=25= 上是否存在 mocking a sealed class 的可能性].