在@Rule 之前通过@Mock 初始化模拟
Initialize mocks via @Mock before @Rule
我有一个测试 class,它正在测试 Dropwizard 资源并使用 JUnit 测试规则 ResourceTestRule
。它设置了许多模拟,我想替换这个成语:
Foo foo = mock(Foo.class);
这有点冗长
@Mock Foo foo;
但是 Dropwizard ResourceTestRule
需要像这样引用这些模拟
@Rule
public ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new BarResource(foo))
.build();
我的问题是 @Mock
之前的 @Rule
运行 初始化模拟,因此 BarResource
实例化时 foo
为空,并且然后我在测试 运行.
时得到空指针异常
这是一个没有使用 Dropwizard 的最小示例来说明问题:
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TestTest {
@Mock String foo;
@Rule
public TestRule testRule = new TestRule() {
{
assert foo != null; // <<< this assertions fails
}
@Override
public Statement apply(Statement statement, Description description) {
return statement;
}
};
@Test
public void test() {
}
}
如果我可以控制 @Mock
和 @Rule
之间的顺序,我就可以避免这个问题。或者也许还有其他我没有想到的选择。
感谢任何建议,谢谢!
这不是@Rule
注解的问题,而是测试class的成员变量初始化的问题。创建测试实例时将初始化规则实例(resources
或 testRule
)。即使没有附加 @Rule
注释也会发生这种情况(这是简单的 java 逻辑:构造对象实例时,将在构造过程中初始化其所有成员变量)。
因此,当 Mockito 创建 foo
模拟时,resources
或 testRule
已经创建。如果您改为使用 MockitoRule
,此行为不会改变。
而 @Rule
注解只是告诉 JUnit 使用创建的对象作为规则,它并不控制规则的创建。
所以我想唯一的解决方案确实是在测试初始化期间也创建 foo
模拟,即使用 Foo foo = mock(Foo.class)
我有一个测试 class,它正在测试 Dropwizard 资源并使用 JUnit 测试规则 ResourceTestRule
。它设置了许多模拟,我想替换这个成语:
Foo foo = mock(Foo.class);
这有点冗长
@Mock Foo foo;
但是 Dropwizard ResourceTestRule
需要像这样引用这些模拟
@Rule
public ResourceTestRule resources = ResourceTestRule.builder()
.addResource(new BarResource(foo))
.build();
我的问题是 @Mock
之前的 @Rule
运行 初始化模拟,因此 BarResource
实例化时 foo
为空,并且然后我在测试 运行.
这是一个没有使用 Dropwizard 的最小示例来说明问题:
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class TestTest {
@Mock String foo;
@Rule
public TestRule testRule = new TestRule() {
{
assert foo != null; // <<< this assertions fails
}
@Override
public Statement apply(Statement statement, Description description) {
return statement;
}
};
@Test
public void test() {
}
}
如果我可以控制 @Mock
和 @Rule
之间的顺序,我就可以避免这个问题。或者也许还有其他我没有想到的选择。
感谢任何建议,谢谢!
这不是@Rule
注解的问题,而是测试class的成员变量初始化的问题。创建测试实例时将初始化规则实例(resources
或 testRule
)。即使没有附加 @Rule
注释也会发生这种情况(这是简单的 java 逻辑:构造对象实例时,将在构造过程中初始化其所有成员变量)。
因此,当 Mockito 创建 foo
模拟时,resources
或 testRule
已经创建。如果您改为使用 MockitoRule
,此行为不会改变。
而 @Rule
注解只是告诉 JUnit 使用创建的对象作为规则,它并不控制规则的创建。
所以我想唯一的解决方案确实是在测试初始化期间也创建 foo
模拟,即使用 Foo foo = mock(Foo.class)