创建SqlCeLockTimeoutException实例
本文关键字:实例 SqlCeLockTimeoutException 创建 | 更新日期: 2023-09-27 18:03:37
出于单元测试的目的,我想创建一个类型为SqlCeLockTimeoutException
的模拟对象
[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)
{
}
}
但是,在创建实例时,我一直得到以下异常:
测试方法Foo抛出异常:
system . runtime . serializize . serializationexception: Member 'ClassName' 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....
为了解决上述问题,我将受保护的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
也需要一个属性__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;
}
[Fact]
public void ConstructTest2()
{
var info = new SerializationInfo(typeof(CvmpApplicationException), new MyFormatConverter());
info.AddValue("ClassName", typeof(CvmpApplicationException).FullName);
info.AddValue("Message", "test");
info.AddValue("InnerException", new Exception());
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 TestCvmpApplicationException(
info,
new StreamingContext(StreamingContextStates.All));
}
private class MyFormatConverter : IFormatterConverter
{
public object Convert(object value, Type type)
{
return value;
}
public object Convert(object value, TypeCode typeCode)
{
return value;
}
public bool ToBoolean(object value)
{
return true;
}
public byte ToByte(object value)
{
return 1;
}
public char ToChar(object value)
{
throw new NotImplementedException();
}
public DateTime ToDateTime(object value)
{
return DateTime.Now;
}
public decimal ToDecimal(object value)
{
return 1;
}
public double ToDouble(object value)
{
return 1D;
}
public short ToInt16(object value)
{
return 1;
}
public int ToInt32(object value)
{
return 1;
}
public long ToInt64(object value)
{
return 1;
}
public sbyte ToSByte(object value)
{
return 1;
}
public float ToSingle(object value)
{
return 1;
}
public string? ToString(object value)
{
return "Message";
}
public ushort ToUInt16(object value)
{
return 1;
}
public uint ToUInt32(object value)
{
return 1;
}
public ulong ToUInt64(object value)
{
return 1;
}
}
private class TestCvmpApplicationException : CvmpApplicationException
{
public TestCvmpApplicationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}