2008-12-11 54 views
4

我想知道单元测试和使用语句是否可以真正结合在一起,因为没有办法模拟在使用语句中实例化的一次性对象。我将如何能够有效地单元测试包含以下使用语句的方法?包含使用语句的单元测试方法

 
public void MyMethod() 
{ 
    using(MyDisposableClass disp = new MyDisposableClass()) 
    { 
     ... 
    } 
} 

当你在进行单元测试时,是否使用简单禁止的语句?

任何意见赞赏。

+0

不错的q。替代品,我能想到的是比原来更多的工作.. – Gishu 2008-12-11 10:48:48

回答

4

不,使用语句当然不禁止。但是MyDisposableClass实际上做了什么?这让我觉得这不是使用陈述成为问题的真正问题 - 这是创建一个您想要模拟的新对象的方法问题 - 问题。

你真的需要模拟MyDisposableClass吗?它可以传入MyMethod而不是在它内部创建吗?与往常一样,诀窍是如何在进程中插入并注入自己的对象...

+0

MyDisposableClass真的是一个外部系统的适配器,我需要Connect(),Login()和LogOut()处置。如果我将它作为参数发布,我会在父方法中遇到问题吗? – Fadeproof 2008-12-11 11:09:23

3

既然你要嘲笑资源类我假设你已经有

interface IResource : IDisposable 
{ 
     void DoSomething(); 
} 

class DisposableResource : IResource 
{ 
    public void Dispose()  { Console.WriteLine("That's it. I'm outta here!"); } 
    public void DoSomething() { Console.WriteLine("Hard work this"); } 
} 

为了能够注入obj,你需要一个缝..即GetResource()

class MyClass 
{ 
    protected virtual IResource GetResource() 
    { 
     return new DisposableResource(); 
    } 
    public void MyMethod1() 
    { 
     using (IResource r = GetResource()) 
     { 
      r.DoSomething(); 
     } 
    } 
} 

在您的测试代码中,只需简单地继承并重写GetResource()以返回一个模拟。

class MySubClassForTest : MyClass 
{ 
    protected override IResource GetResource() 
    { 
     return new MockResource(); 
    } 
} 
class MockResource : IResource // or use a mock framework to create one 
{ 
    public void DoSomething()  { Console.WriteLine("Me work?"); } 
    public void Dispose()   { Console.WriteLine("Disposed Mock!"); } 
} 

就是这样。

MyClass obj = new MyClass();   // production code 
obj.MyMethod1(); 

obj = new MySubClassForTest();   // test code 
obj.MyMethod1(); 
1

TypeMock将允许你嘲笑这一点。它通过动态修改IL来工作,因此不会嘲笑你无法模拟的东西。

但即使使用TypeMock,您仍应该看看Jon Skeet和Pop Catalin在上面所说的内容。如果您尝试减少依赖关系的数量,您的代码将更容易维护。