- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
出于单元测试目的,我想创建一个类型为 SqlCeLockTimeoutException
的模拟对象
因为它的构造函数是 protected ,所以我在测试中创建了一个扩展类:
[Serializable]
private class TestableSqlCeLockTimeoutException : SqlCeLockTimeoutException
{
public TestableSqlCeLockTimeoutException()
: this(new SerializationInfo(typeof (TestableSqlCeLockTimeoutException),
new FormatterConverter()),
new StreamingContext())
{
}
protected TestableSqlCeLockTimeoutException(SerializationInfo info,
StreamingContext context)
: base(info, context)
{
}
}
但是,我在创建实例时不断收到以下异常:
Test method Foo threw exception:
System.Runtime.Serialization.SerializationException: Member 'ClassName' was not found.
为什么我总是收到它?我尝试使用 Serializable
属性但无济于事。
任何解决方法也会有所帮助。
最佳答案
@Mugan 你问了一个非常有趣的问题!为了回答这个问题,我不得不反编译 SqlCeLockTimeoutException
。当我试图帮助你时,我学到了很多东西。谢谢。
出现问题是因为 System.Exception
C`tor 需要反序列化一些属性:
[System.Security.SecuritySafeCritical] // auto-generated
protected Exception(SerializationInfo info, StreamingContext context)
{
//some validation
_className = info.GetString("ClassName");
_message = info.GetString("Message");
_data = (IDictionary)(info.GetValueNoThrow("Data",typeof(IDictionary)));
_innerException = (Exception)(info.GetValue("InnerException",typeof(Exception)));
_helpURL = info.GetString("HelpURL");
_stackTraceString = info.GetString("StackTraceString");
_remoteStackTraceString = info.GetString("RemoteStackTraceString");
_remoteStackIndex = info.GetInt32("RemoteStackIndex");
_exceptionMethodString = (String)(info.GetValue("ExceptionMethod",typeof(String)));
HResult = info.GetInt32("HResult");
_source = info.GetString("Source");
//some bla bla....
为了解决上面的问题我把protected C`tor改成了public然后使用:
var info = new SerializationInfo(typeof (TestableSqlCeLockTimeoutException),
new FormatterConverter());
info.AddValue("ClassName", string.Empty);
info.AddValue("Message", string.Empty);
info.AddValue("InnerException", new ArgumentException());
info.AddValue("HelpURL", string.Empty);
info.AddValue("StackTraceString", string.Empty);
info.AddValue("RemoteStackTraceString", string.Empty);
info.AddValue("RemoteStackIndex", 0);
info.AddValue("ExceptionMethod", string.Empty);
info.AddValue("HResult", 1);
info.AddValue("Source", string.Empty);
new TestableSqlCeLockTimeoutException(info,new StreamingContext());
然后这次从 SqlCeException
引发了新的异常。 SqlCeException
Ctor还需要一个属性__Errors__
:
protected SqlCeException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
if (info == null)
throw new ArgumentNullException("info");
this.Errors = (SqlCeErrorCollection) info.GetValue("__Errors__", typeof (SqlCeErrorCollection));
}
SqlCeErrorCollection
Ctor 是内部的,因此我使用了 Reflaction
来创建一个实例:
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
CultureInfo culture = null; // use InvariantCulture or other if you prefer
object instantiatedType =
Activator.CreateInstance(typeof(SqlCeErrorCollection), flags, null, null, culture);
info.AddValue("__Errors__", instantiatedType);
现在一切正常。我最终得到了一个创建方法:
private static SqlCeLockTimeoutException CreateSqlCeLockTimeoutExceptionForTest()
{
var info = new SerializationInfo(typeof (TestableSqlCeLockTimeoutException),
new FormatterConverter());
info.AddValue("ClassName", string.Empty);
info.AddValue("Message", string.Empty);
info.AddValue("InnerException", new ArgumentException());
info.AddValue("HelpURL", string.Empty);
info.AddValue("StackTraceString", string.Empty);
info.AddValue("RemoteStackTraceString", string.Empty);
info.AddValue("RemoteStackIndex", 0);
info.AddValue("ExceptionMethod", string.Empty);
info.AddValue("HResult", 1);
info.AddValue("Source", string.Empty);
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
CultureInfo culture = null; // use InvariantCulture or other if you prefer
object instantiatedType = Activator.CreateInstance(typeof (SqlCeErrorCollection),
flags, null, null, culture);
info.AddValue("__Errors__", instantiatedType);
return new TestableSqlCeLockTimeoutException(info, new StreamingContext());
}
您还可以使用 Reflaction
创建 SqlCeLockTimeoutException
的新实例,而不是 TestableSqlCeLockTimeoutException
:
private static SqlCeLockTimeoutException CreateSqlCeLockTimeoutExceptionForTest()
{
BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
CultureInfo culture = null; // use InvariantCulture or other if you prefer
object instantiatedType = Activator.CreateInstance(typeof (SqlCeErrorCollection),
flags, null, null, culture);
object result = Activator.CreateInstance(typeof(SqlCeLockTimeoutException),
flags, null, new []{instantiatedType}, culture);
return (SqlCeLockTimeoutException)result;
}
关于c# - 创建 SqlCeLockTimeoutException 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31498831/
出于单元测试目的,我想创建一个类型为 SqlCeLockTimeoutException 的模拟对象 因为它的构造函数是 protected ,所以我在测试中创建了一个扩展类: [Serializab
我是一名优秀的程序员,十分优秀!