调用了构造函数中的验证方法
Verify method in constructor was called
我有一个调用方法的构造函数,如下所示:
public Foo(boolean runExtraStuff) {
if (runExtraStuff){
doExtraStuff();
}
}
doExtraStuff()
方法正在 运行 加入一些不容易自我模拟的额外命令(例如数据库检查以初始化某些变量)。也许构造函数不这样做会更好,但这是我目前必须使用的代码。
我想创建一个单元测试以确保当布尔值 runExtraStuff
为真时调用 doExtraStuff()
而当布尔值为假时不调用 运行。我正在使用 JMockit。
但是,我不确定如何实现这一点。通常我会在模拟对象上使用 Verifications
,但由于我正在测试构造函数,所以我不能以这种方式使用模拟对象。那么如何验证构造函数中的方法是否被调用?
好吧,直截了当的答案根本不使用 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() 调用的期望设置为 times = 0
这很简单,即使它需要部分模拟:
@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 或其他可用方法检查对象的状态。
我有一个调用方法的构造函数,如下所示:
public Foo(boolean runExtraStuff) {
if (runExtraStuff){
doExtraStuff();
}
}
doExtraStuff()
方法正在 运行 加入一些不容易自我模拟的额外命令(例如数据库检查以初始化某些变量)。也许构造函数不这样做会更好,但这是我目前必须使用的代码。
我想创建一个单元测试以确保当布尔值 runExtraStuff
为真时调用 doExtraStuff()
而当布尔值为假时不调用 运行。我正在使用 JMockit。
但是,我不确定如何实现这一点。通常我会在模拟对象上使用 Verifications
,但由于我正在测试构造函数,所以我不能以这种方式使用模拟对象。那么如何验证构造函数中的方法是否被调用?
好吧,直截了当的答案根本不使用 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:在第二次测试
这很简单,即使它需要部分模拟:
@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 或其他可用方法检查对象的状态。