5

我想知道单元测试和 using 语句是否真的可以齐头并进,因为没有办法模拟在 using 语句中实例化的一次性对象。我如何能够有效地对包含以下 using 语句的方法进行单元测试?

公共无效我的方法()
{
   使用(MyDisposableClass disp = new MyDisposableClass())
   {
       ...
   }
}

当您进行单元测试时,是否完全禁止使用语句?

任何意见表示赞赏。

4

4 回答 4

4

不,当然不禁止使用语句。但是 MyDisposableClass 实际上做了什么?令我震惊的是,这实际上并不是 using 语句成为问题的问题-而是创建要模拟的新对象的方法问题-这就是问题所在。

你真的需要模拟 MyDisposableClass 吗?它可以传递给 MyMethod 而不是在其中创建吗?与以往一样,诀窍是弄清楚如何在需要时加入进程并注入自己的对象......

于 2008-12-11T10:28:15.893 回答
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();
于 2008-12-11T11:10:05.030 回答
1

使用工厂模式和/或依赖注入模式将大大简化您对实例化自己资源的方法进行单元测试的方式。

这是一个很好的阅读主题:

于 2008-12-11T10:42:37.690 回答
1

TypeMock 将允许你模拟它。它通过动态修改 IL 来工作,因此在模拟你无法模拟的东西时没有问题。

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

于 2008-12-11T11:14:59.247 回答