我正在使用NUnit和C#对一个老式的COM/ActiveX控件进行单元测试。我做的每件事都是动态的,没有引用或编译时类型的信息,因为我测试的控件主要来自javascript——当然,javascript做的每一件事都很动态。我想挂接一些事件处理程序,并确保事件被适当地触发,但我找不到事件!我使用System.Activator.CreateInstance动态构造控件的实例,如下所示(省略了一些细节;-):
Type T = Type.GetTypeFromCLSID(guid);
eztwain = System.Activator.CreateInstance(T);
EZTwainX = eztwain.GetType();
性能和方法测试效果良好,如
EZTwainX.InvokeMember("Clear", BindingFlags.InvokeMethod, null, eztwain, null);
Assert.AreEqual(0, (int)EZTwainX.InvokeMember("ImageCount", BindingFlags.GetProperty, null, eztwain, null), "ImageCount");
以下所有操作都失败,返回null或空数组,或引发"找不到名称"异常(视情况而定):
EZTwainX.GetEvent("AcquireDone"); // returns null
EZTwainX.GetEvents(); // returns empty array
EZTwainX.GetEvents(BindingFlags.Public | // returns empty array
BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
PropertyInfo propertyInfo = EZTwainX.GetProperty("Events", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); // returns null
MemberInfo[] mimfo = EZTwainX.GetMember("AcquireDone", MemberTypes.Event, BindingFlags.Public | BindingFlags.NonPublic); // returns empty array
我只是假设(嗯哼)我可以使用反射API做一些事情,相当于:
eztwain.AcquireDone += <event handler>;
但我不知道那是什么等价物。编辑:我相信控件上的那个事件,因为在Javascript中它可以工作(并捕获事件):
eztwain.attachEvent("AcquireDone", function() { me.onAcquireDone(); });
了解如何:处理COM源引发的事件
另外,请注意可以使用(Ildasm.exe(IL Disassembler))获取事件签名的实用程序。