【问题标题】:Unit testing and factories for mocks模拟单元测试和工厂
【发布时间】:2019-11-15 20:50:10
【问题描述】:

假设我有一个需要测试的 C 类。它的部分工作是创建许多其他重要的类对象(每个都有自己的业务逻辑)并在这些新对象上调用各种方法。我希望能够在不测试 C 创建的其他对象的实现的情况下测试 C 类。唯一真正的解决方案是创建一个创建那些非平凡对象的工厂,然后将一个模拟的工厂实例传递给测试?我不想有一个工厂来创建那些其他重要的对象,但另一方面我不希望每个重要的类都有一个工厂。

还有其他建议吗?

编辑:根据要求添加了一些伪代码

public B doIt()
{
  List<A> as = getListOfAsFromDatabase();
  AParser AParser = new AParser();
  boolean foo = aParser.parse(as); // may modify the list of A's
  B b = new B();
  return b.add(foo, as);
}

【问题讨论】:

  • 您是在用一种方法创建那些重要的对象吗?你能参数化它们吗?
  • 如果你不想要一个工厂,也不想每个班级一个工厂,那么剩下的唯一选择就是通过多个工厂,每个工厂负责创建 1 个或多个对象。或者,这些对象中的一些应该作为另一个父对象的字段组合在一起,由父对象工厂创建。
  • @Anatolii 是的,用一种方法创建。参数化它们是什么意思?
  • @JBNizet 今天的情况是我只需要创建一种重要类型的对象。我可以为这个创建一个工厂。我担心的是,如果明天我需要再创建 5 个非平凡类型的对象。正确,我不想再创建 5 个工厂。父工厂/重构在未来可能有意义,但对象今天不能以这种方式关联/重构。
  • @jordan 您能否添加一些代码来解释您要测试哪种方法以及需要跳过哪种方法?

标签: java unit-testing mocking


【解决方案1】:

如果依赖对象的创建是在成员级别,我们可能会使用 Mockito 和 PowerMock 来创建模拟并更新成员以模拟依赖。我正在使用静态内部类来简化此操作,此解决方案也适用于常规类。

public class Test1 {
    @Test
    public void test() {
        B mockedb = org.mockito.Mockito.mock(B.class);
        A a = new A();
        org.powermock.reflect.Whitebox.setInternalState(a, "b", mockedb);
        a.exe();
    }

    public static class A {
        private B b = new B();

        public void exe() {
            List<String> l = new ArrayList<>();
            l.add("a");
            b.exeB(l);
            System.out.println(l);
        }

        public static class B {
            public void exeB(List<String> s) {
                s.add("b");
            }
        }

    }

}

【讨论】:

  • 我知道这些反射方法,但它们对我来说似乎是一种黑客攻击。
  • 这只是测试代码,它不会包含在您的生产代码中。但是,由您决定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多