2011-03-22 15 views
12

.NET中是否有可能在子进程中执行方法(委托,静态方法等)? System.Diagnostics.Process似乎需要一个实际的文件名,这意味着需要一个单独的可执行文件。开始一个执行委托的新进程

我想要做的是在单元测试中验证在进程退出时清理了OS资源。我知道,可能使用CodeDOM或IL代来创建这样一个程序集并执行它,但单元测试的重点是隔离组件部分,而不是创建复杂性。出于同样的原因,我想避免一个单独的程序集。

理想情况下,我会做这样的事情:

public static void CreateCounter() 
{ 
    var counter = new PerformanceCounter("category", "counter", "instance"); 
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process; 
} 

[Test] 
public void TestResourceDisposal() 
{ 
    // Start child process to execute CreateCounter() 
    ... 
    // verify the resource is disposed 
} 

回答

6

首先,没有,有没有办法做到这一点。我的过程意味着一个.exe。这不是Unix,你可以派生一个父进程副本。

我只是创建一个微小的.exe来运行。你需要用不同的性能计数器来运行测试吗?如果它与一个人一起工作,那么它肯定会与他们中的任何人一起工作?

+0

所以看起来你是正确的 - 我没有找到可以做到的管理方式。我已经使用了CodeDOM路径,并且正在生成微型的.exe。谢谢! – Ben 2011-03-22 23:48:47

0

我不确定你想要完成什么,但是从CreateCounter返回性能计数器实例并使用using指令会更容易,因为PerformanceCounter是IDisposable。像这样:

using (var counter = CreateCounter()) 
{ 
    // Do some work 
} 

然后,即使在测试过程中抛出计数器,计数器也会始终清理干净。

否则,我想你想要的是create a new thread。然后你可以thread.Join()等待线程完成。有关更多信息,请参阅System.Threading namespace

+0

不幸的是,既不调用Dispose()也不产生线程就足够了。我特别针对发布(通过Windows)发布的perf计数器实例名称进行了测试,该名称指定仅在进程退出时发生 - 线程连接将不具有所需的效果,并且Dispose()也不会发生。 – Ben 2011-03-22 05:24:04

2

你在说什么不是单元测试。与实际(昂贵的)操作系统服务交互违反了单元测试旨在争取的隔离基本原则。

如果您的目的是测试在更多的终端到终端的时尚代码,与性能计数器等实际互动,这将是一个集成测试,应该在一个更“重型写“的方式,即根据需要编写单独的EXE,运行任何复杂的设置或清理步骤等。

如果您需要对处理性能计数器的组件进行单元测试,则必须首先将此依赖关系抽象出来。通常,您将创建一个表示性能计数器表面区域的基类或接口,然后创建某种类型的test double以在(测试)运行时替换其功能。真正的系统将使用一个简单的包装器,委托给实际的性能计数器,并将通过上面的集成测试来执行。

从阅读你上面的评论,它几乎听起来像你试图测试.NET框架的保证。我会质疑这是否真的有必要,因为它已经很好地测试过了,虽然也许你想测试你的代码是否正确使用它(在这种情况下,你可以根据你正在寻找的验证来进行单元测试或集成测试)。

+0

WRT你最后一段:是和否。我实际上在柜台周围测试我们自己的包装纸;通常一个模拟就足够了,但在这种情况下并不多。表演柜台有一段历史(以我的经验)徘徊,并不总是按照他们应有的方式行事;测试(通过任何名称)应该在发生时隔离这种行为。 – Ben 2011-03-22 18:35:44