调用了构造函数中的验证方法

时间:2015-04-20 16:35:06

标签: java jmockit

我有一个调用方法的构造函数,如下所示:

public Foo(boolean runExtraStuff) {
    if (runExtraStuff){
        doExtraStuff();
    }
}

doExtraStuff()方法正在运行一些其他命令,这些命令本身不容易被模拟(比如数据库检查以初始化一些变量)。也许构造函数不会这样做会更好,但这是我现在需要处理的代码。

我想创建一个单元测试,以确保在布尔值doExtraStuff()为真时调用runExtraStuff,在布尔值为假时不运行。我正在使用JMockit。

但是,我不确定如何实现这一目标。通常我会在模拟对象上使用Verifications,但由于我正在测试构造函数,所以我不能以这种方式使用模拟对象。那么如何验证构造函数中的方法是否被调用?

2 个答案:

答案 0 :(得分:3)

它很容易,即使它需要部分嘲笑:

@Test
public void runsSetupWhenRequestedOnFooInitialization()
{
    // Partially mocks the class under test:
    new Expectations(Foo.class) {};

    final Foo foo = new Foo(true);

    // Assuming "setup" is not private (if it is, use Deencapsulation.invoke):
    new Verifications() {{ foo.setup(); }};
}

@Test
public void doesNotRunSetupWhenNotRequestedOnFooInitialization()
{
    new Expectations(Foo.class) {};

    final Foo foo = new Foo(false);

    new Verifications() {{ foo.setup(); times = 0; }};
}

当然,在这种情况下避免嘲笑可能会更好;相反,测试应该通过getter或其他可用方法检查对象的状态,如果可能的话。

答案 1 :(得分:1)

嗯,直截了当的答案根本就没有使用JMockit ..

在src / main / java / example ..

package example;

public class Foo {
    private boolean setupRan = false;

    public Foo(boolean runSetup) {
        if (runSetup) setup();
    }

    public void setup() {
        setupRan = true;
    }

    public boolean getSetupRan() {
        return setupRan;
    }
}

在src / test / java / example ..

package example;

import static org.assertj.core.api.Assertions.*;

import org.junit.Test;

public class FooTest {

    private Foo testSubject;

    @Test
    public void should_run_setup() {
        testSubject = new Foo(true);
        assertThat(testSubject.getSetupRan()).isTrue();
    }

    @Test
    public void should_not_run_setup() {
        testSubject = new Foo(false);
        assertThat(testSubject.getSetupRan()).isFalse();
    }

}

我会走出困境,猜测你对这里的局部模拟感兴趣:

在src / main / java / example ..

package example;

public class Foo1 {
    public Foo1(boolean runSetup) {
        if (runSetup) setup();
    }

    public void setup() {
        System.out.println("in setup()");
    }
}

在src / test / java / example ..

package example;

import static org.assertj.core.api.Assertions.*;

import mockit.Expectations;
import mockit.Mocked;
import org.junit.Test;

public class Foo1Test {

    // hateful partial mocking of test subject!
    @Mocked({"setup()"})
    private Foo1 testSubject;

    @Test
    public void should_run_setup() {
        new Expectations() {{
            testSubject.setup(); // setup() is called
        }};
        testSubject = new Foo1(true);
    }

    @Test
    public void should_not_run_setup() {
        new Expectations() {{
            testSubject.setup(); times = 0;
        }};
        testSubject = new Foo1(false);
    }
}

编辑1:请注意,由于方法被模拟,您无法看到println输出。
编辑2:在第二次测试中将testSubject.setup()调用的期望设置为次数= 0