如何跳过在单元测试的方法内部的方法调用

时间:2013-05-15 16:00:10

标签: c# unit-testing

我有一个方法调用,我是单元测试。在该方法调用内部,它调用一个将抛出错误的方法,因为它试图与单元测试运行时无法使用的设备进行通信。有没有办法避免调用内部方法调用?

环境:IDE中的C#Visual Studio 2010单元测试

7 个答案:

答案 0 :(得分:4)

如果您要对具有外部依赖关系的类进行单元测试,则必须使用注入的接口隔离外部依赖项。

interface IDevice
{
    void Run();
}

interface IDeviceOperator
{
    void Operate();
}

class DeviceOperator : IDeviceOperator 
{
    private readonly IDevice _device;

    public DeviceOperator(IDevice device)
    {
        _device = device;
    }

    public void Operate()
    {
        _device.Run();

        // test other stuff here
    }
}

[TestFixture]
public class DeviceOperatorTests
{
    [Test]
    public void Test_DeviceOperator_Operate()
    {
        IDevice device = A.Fake<IDevice>(); // Using FakeItEasy 3rd party mocking framework syntax
        DeviceOperator deviceOperator = new DeviceOperator(device);

        deviceOperator.Operate();
    }
}

答案 1 :(得分:2)

进行单元测试时,必须为所有外部依赖项创建模拟或存根。一个可以帮助你的框架是Moq(如果你想探索,它有很多模拟框架)。

这些模拟或存根只是提供必要的交互和数据以通过测试的外观。

如果您提供有关不可用设备的更多详细信息,我们可能会为您提供更多帮助。

答案 2 :(得分:1)

可能有更好的方法,但有一两次我遇到过这种情况,其中一个方法调用另一个复杂的方法,并在你正在测试的方法的末尾添加一个可选参数,如

public void DoSomething(int number, bool skipMethod= false)
{
    if(!skipMethod)
        MethodThatWillBreak();
{

因此,在正常的跑步过程中,它会很好,但在你的单元测试中你可以做到

DoSomething(2,true);

但实际上,它表明你需要对你的代码进行一些重构,因为你的单元测试应该只打一个“单位”。如果你可以在不调用MethodThatWillBreak的情况下测试方法,那么它首先在那里做什么。

答案 3 :(得分:1)

查看Michael Feathers的Working Effectively with Legacy Code书籍 - 它有很多关于处理尚未进行单元测试的代码的建议。

书中涵盖的可能方法:

  • 提取界面中的依赖 - 理想的方法(参见jamespconnor的回答)
  • 使用标记来绕过呼叫(参见Colm Prunty的回答)
  • 提取调用虚方法并覆盖单元测试中使用的派生类
  • 传递委托(可能比完整界面/派生的影响小)

从类中派生的样本:

public class WithComplexDependency
{
   public void DoSomething()
   {
     // Extract original code into a virtual protected method
     // dependency.MethodThatWillBreak();
     CallMethodThatWillBreak();
   }

   virtual protected void CallMethodThatWillBreak()
   {
      dependency.MethodThatWillBreak();
   }
}
测试代码中的

派生自类并提供自己的实现:

public class WithMockComplexDependency : WithComplexDependency
{
   // may also need to add constructor to call original one.

   override protected void CallMethodThatWillBreak()
   {
      // do whatever is needed for your test
   }
}

...
WithComplexDependency testObject = new WithMockComplexDependency();
testObject.DoSomething(); // now does not call dependency.MethodThatWillBreak()
...

答案 4 :(得分:0)

要正确进行单元测试,您应该将通信与您要测试的类中的设备分离!摘要在另一个实现接口的类中对设备进行分解,在被测对象的ctor中注入通信类,现在可以从外部注入模拟实现并避免错误,mmock实现也可以记录调用它或以预定义的方式响应以简化测试。 读出依赖注入和控制反转

答案 5 :(得分:0)

通常,您将从正在测试的类中提取外部依赖项,并在单元测试中将它们与假的相互交换。您可以隔离它们并测试您感兴趣的部分。我建议您查看控制反转以及许多模拟框架之一(MoqRhino Mocks等。)

答案 6 :(得分:0)

你可能不想跳过外部。相反,您希望隔离外部依赖项,例如访问外部设备。有很多方法可以做到这一点 一个。您可以使用第三方隔离框架,如Moq或RhinoMock等 湾您可以使用Moles框架(因为您使用的是VS2010) - 用委托替换.NET方法 http://research.microsoft.com/en-us/projects/moles/ C。付费隔离框架,如TypeMock。 d。或者只是手写的虚假实现,在接口中使用,你的测试使用Fake实现。