【问题标题】:How to mock constructor of subclass in Junit?如何在 Junit 中模拟子类的构造函数?
【发布时间】:2016-01-02 10:54:07
【问题描述】:

类结构如下所示:

class A {
 protected String a;
 protected String b;

 A(String b1) {
    new A("A111", b1);
 }

 A(String a1, String b1) {
   a = a1;
   b = b1;
 }
}

class B extends A {

  B(String b) {
    super("A", b);
  }
}

我需要编写 JUnit 测试用例,并且需要模拟 A 类的构造函数,这样每当需要为 B 类创建对象时,A 类的模拟构造函数就应该被调用并从模拟构造函数返回对象。

我尝试了以下操作:

       new MockUp<A>() {

            @Mock
            public void $init(String b1) {
                new A("A11111111", b1);
            }
        };

但在模拟构造函数中创建的对象尚未返回。

【问题讨论】:

  • 我不明白你的要求。你能多解释一下你想做什么以及你想测试什么吗?
  • 好像想把超类的构造函数和子类分开,只测试子类的逻辑(通过mock超类)?但事情是这样的:构造函数并没有真正返回对象 - 当你调用 super() 时,你没有将它分配给任何东西,因为它在 this 上运行......所以你不能“调用并从模拟返回对象构造函数”在这种情况下。
  • 我想模拟单个参数化构造函数,从模拟构造函数中,我想使用两个参数化构造函数创建对象并返回相同的对象以供进一步使用。
  • @dcsohl 是的..你说得对......我们怎样才能做到这一点?

标签: java unit-testing junit constructor jmockit


【解决方案1】:

好的,你走在正确的道路上......它需要@MockMockUpInvocationDeencapsulation 的组合......你必须在你的$init 中添加一个Invocation mock 方法,然后使用 Deencapsulation 在A internals 上四处寻找。这是一个例子。我使用了您的 A 和 B 类,只是稍微清理了它们并添加了吸气剂以方便使用。我故意不添加 setter,所以我可以展示如何解决缺少 setter 的问题。

package com.example.dcsohl;

import org.junit.Test;

import mockit.Deencapsulation;
import mockit.Invocation;
import mockit.Mock;
import mockit.MockUp;

public class TestTest {

    public static class A {
        protected String a;
        protected String b;

        public A(String b1) {
            this("A111", b1);
        }

        public A(String a1, String b1) {
            a = a1;
            b = b1;
        }
    }

    public static class B extends A {
        public B(String b1) {
            super("A", b1);
        }

        public String getA() {
            return this.a;
        }

        public String getB(){
            return this.b;
        }
    }

    @Test
    public void test() {
        new MockUp<A>() {
            @Mock public void $init(Invocation inv, String a1, String b1) {
                A a = inv.getInvokedInstance();
                Deencapsulation.setField(a, "b", b1);
            }
        };

        B b = new B("foo");

        System.out.println(b.getA());
        System.out.println(b.getB());

    }

}

您会注意到,最后,打印输出显示我成功设置了b 的值,但是单独留下a,它显示为null

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多