java - 如何使用模拟对象编写单元测试?

标签 java unit-testing mocking

我读的模拟示例越多,我就越困惑......

我有调用 FatDude 类 eatThemAll() 的 classA 方法 eat()

public class classA {

   FatDude dude = new FatDude();

   public String eat() {
        String result = dude.eatThemAll();
   }
}

public class FatDude {
   public String eatThemAll() {
       return "never full";
   }
}

现在我想通过模拟 FatDude 类来测试 classA eat() 方法。

public class MockFatDude extends FatDude {
   //override
   public String eatThemAll() {
      return "very full";
   }
}
-------------  test --------------
public class DoTest {

    public void runTest() {
         classA cl = new ClassA();
         String out = cl.eat();
         assertEqual(out, "very full");
    }
}

这个 DoTest runTest() 当然不会使用 MockFatDude 类。我能想到的一种方法是更改​​代码以将 FatDude 传递给 ClassA 的 eat() 方法,例如:

public class classA {

       public String eat(FatDude dude) {
            String result = dude.eatThemAll();
       }
   }

然后把我的测试方法改成:

public class DoTest {

        public void runTest() {
             classA cl = new ClassA();
             String out = cl.eat(new MockFatDude());
             assertEqual(out, "very full");
        }
    }

但是如您所见,我不得不更改源代码以满足我的需要。 这是正确的做法吗?如果不允许我更改源代码怎么办? 我知道如果我应用 TDD 概念,可以更改源代码,但我想听听 如果我上面显示的是正确的方法,请提出一些意见或建议。

最佳答案

模拟和 Dependency Inversion Principle (DIP) 齐头并进,在大多数语言中,Mocks 通过接口(interface)解耦类来发挥最佳作用。

在你的例子中,这将在你不需要更改代码的情况下工作:(编辑:我的意思是,将来,如果你以这种方式设计你的应用程序,你将不需要更改代码来模拟依赖关系:))

  • 抽象一个接口(interface) IDude
  • 具体类 FatDude(和 MockFatDude)应该实现 IDude 接口(interface)
  • 提供一个 IDude 实例被“设置”或注入(inject)到 classA 中的机制——依赖注入(inject)(构造函数或获取/设置);或服务定位器模式效果最好(替换具体的类工厂)

另请注意,许多模拟框架实际上允许您“即时”构建 Mock 具体类(参见 MoQ 等),因此您可以直接在单元测试中创建 MockFatDude 的功能。

关于java - 如何使用模拟对象编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4396113/

相关文章:

java - 基本多线程程序

c# - ResetDefaults() 方法在 StructureMap 中不起作用

python - 在 autospeccing 时模拟 side_effect 为函数提供额外的参数

c# - Visual Studio 单元测试 C# 的命令行参数

python - 如何为 python 单元测试提供模拟类方法?

java - carddav caldav - 在 AppEngine 中同步

Console() 中的 java.lang.System 错误

java - Glassfish:将 Java 类存储在 docroot 文件夹中?

IOS:使用dispatch_async的单元测试未执行

ios - xcode 中性能测试的单独方案