C# 单元测试卡在 COM 对象上
C# unit tests get stuck on COM objects
我正在用 C# 开发一个项目,我有一段代码可以在 main()
中完美运行,但在测试中,调试器卡在 COM 对象调用上,测试无法通过该行。
这是代码:
private ICMSDWorkset CMSWorkset;
private ICMSDProject CMSProject;
[TestMethod()]
public void CMSConnector_EntityProviderTest()
{
string connectionString = @"PATH";
CMSAPI capi = new CMSAPI();
//capi.Init(connectionString, "USER", "Project name");
Init(connectionString, "@SETUP", "iDB_P01");
Terminate();
}
private void Init(String connectionString, string currentUser, string currentProject)
{
CMSWorkset = new CPLTWorkset() as ICMSDWorkset;
CMSWorkset.Init("", "", connectionString);
if (!CMSWorkset.IsInitialized())
throw new ArgumentException(
new StringBuilder().AppendFormat("")
.AppendFormat("initialization failed for connection string '{0}'", connectionString)
.ToString()
);
// set user
ICMSDOwnCollection tmpColl = CMSWorkset.GetAllUsers() as ICMSDOwnCollection;
CMSWorkset.SetCurrentUser(tmpColl.Item(currentUser));
// set project as current in workset
tmpColl = CMSWorkset.GetAllProjects() as ICMSDOwnCollection;
CMSProject = tmpColl.Item(currentProject) as ICMSDProject;
CMSWorkset.SetCurrentProject(CMSProject);
if (!CMSWorkset.IsInitialized())
throw new ArgumentException(
new StringBuilder().AppendFormat("")
.AppendFormat("initialization failed for connection string '{0}', user '{1}' and project name '{2}'",
connectionString, currentUser, currentProject)
.ToString()
);
}
public void Terminate()
{
// do the deallocations; mandatory
CMSWorkset.Terminate();
CMSWorkset = null;
}
当我向前按一步并到达此行时进行测试调试:
CMSWorkset = new CPLTWorkset() as ICMSDWorkset;
调试器停止工作,测试继续运行但仍然停留在该行。没有错误或异常被抛出。
CPLTWorkset
是 COM 对象的包装器。
我检查了 'Native code debugging' 和其他提到的有关 COM 对象的问题,但没有成功。
有没有人知道为什么调试器无法处理该行?或者为什么那条鳕鱼在 main 上工作而不在 tests 上工作?
谢谢!
我的第一个猜测是 new CPLTWorkset()
调用的代码仅适用于标记为 [STAThread]
的线程。您的 Main 方法具有此属性,使主线程成为单线程单元线程,而您的单元测试框架使用的线程则不是。
请注意,只要调用 Thread.SetAparatmentState may not fix this; when a thread is an STA thread, this also implies that an event loop is being pumped on it (e.g. in WinForms, Application.Run 就会被调用)。这在单元测试中很难实现,除非你真的知道你在做什么。
我正在用 C# 开发一个项目,我有一段代码可以在 main()
中完美运行,但在测试中,调试器卡在 COM 对象调用上,测试无法通过该行。
这是代码:
private ICMSDWorkset CMSWorkset;
private ICMSDProject CMSProject;
[TestMethod()]
public void CMSConnector_EntityProviderTest()
{
string connectionString = @"PATH";
CMSAPI capi = new CMSAPI();
//capi.Init(connectionString, "USER", "Project name");
Init(connectionString, "@SETUP", "iDB_P01");
Terminate();
}
private void Init(String connectionString, string currentUser, string currentProject)
{
CMSWorkset = new CPLTWorkset() as ICMSDWorkset;
CMSWorkset.Init("", "", connectionString);
if (!CMSWorkset.IsInitialized())
throw new ArgumentException(
new StringBuilder().AppendFormat("")
.AppendFormat("initialization failed for connection string '{0}'", connectionString)
.ToString()
);
// set user
ICMSDOwnCollection tmpColl = CMSWorkset.GetAllUsers() as ICMSDOwnCollection;
CMSWorkset.SetCurrentUser(tmpColl.Item(currentUser));
// set project as current in workset
tmpColl = CMSWorkset.GetAllProjects() as ICMSDOwnCollection;
CMSProject = tmpColl.Item(currentProject) as ICMSDProject;
CMSWorkset.SetCurrentProject(CMSProject);
if (!CMSWorkset.IsInitialized())
throw new ArgumentException(
new StringBuilder().AppendFormat("")
.AppendFormat("initialization failed for connection string '{0}', user '{1}' and project name '{2}'",
connectionString, currentUser, currentProject)
.ToString()
);
}
public void Terminate()
{
// do the deallocations; mandatory
CMSWorkset.Terminate();
CMSWorkset = null;
}
当我向前按一步并到达此行时进行测试调试:
CMSWorkset = new CPLTWorkset() as ICMSDWorkset;
调试器停止工作,测试继续运行但仍然停留在该行。没有错误或异常被抛出。
CPLTWorkset
是 COM 对象的包装器。
我检查了 'Native code debugging' 和其他提到的有关 COM 对象的问题,但没有成功。
有没有人知道为什么调试器无法处理该行?或者为什么那条鳕鱼在 main 上工作而不在 tests 上工作?
谢谢!
我的第一个猜测是 new CPLTWorkset()
调用的代码仅适用于标记为 [STAThread]
的线程。您的 Main 方法具有此属性,使主线程成为单线程单元线程,而您的单元测试框架使用的线程则不是。
请注意,只要调用 Thread.SetAparatmentState may not fix this; when a thread is an STA thread, this also implies that an event loop is being pumped on it (e.g. in WinForms, Application.Run 就会被调用)。这在单元测试中很难实现,除非你真的知道你在做什么。