I have some JUnit tests that use the TemporaryFolder
@Rule
. They use the TemporaryFolder
in a @Before
method to perform some setup:
我有一些使用TemporaryFolder @Rule的JUnit测试。他们在@Before方法中使用TemporaryFolder来执行一些设置:
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Before
public void init() {
folder.newFile("my-file.txt");
}
@Test
public void myTest() { ... }
Most of the time this works perfectly. However, when using the SpringJUnit4ClassRunner
I find that in some cases the init()
method is invoked before the Statement
inside my TemporaryFolder
instance is applied. Because of this, the temporary folder location is unset (i.e: null
) when folder
is used within init()
and my file ends up in the working directory, not /tmp
.
大部分时间这都很完美。但是,在使用SpringJUnit4ClassRunner时,我发现在某些情况下,在应用TemporaryFolder实例中的Statement之前调用init()方法。因此,在init()中使用文件夹时,临时文件夹位置未设置(即:null),而我的文件最终在工作目录中,而不是/ tmp。
So in some cases @Before
methods are executed ahead of the rules, however, I can't establish a definite pattern. I occasionally see a similar problem with some of my own rule implementations.
所以在某些情况下@Before方法在规则之前执行,但是,我无法建立一个明确的模式。我偶尔会看到一些与我自己的规则实现类似的问题。
Is there any way that I can ensure that my rule statements are applied before any setup methods?
有什么方法可以确保在任何设置方法之前应用我的规则语句?
2 个解决方案
#1
12
In JUnit 4.10, BlockJUnit4ClassRunner (the superclass of SpringJUnit4ClassRunner) appears to take care to construct Statement chains in such a way that rules run before any @Before methods. From JUnit 4.10:
在JUnit 4.10中,BlockJUnit4ClassRunner(SpringJUnit4ClassRunner的超类)似乎注意构造Statement链,使得规则在任何@Before方法之前运行。从JUnit 4.10:
protected Statement methodBlock(FrameworkMethod method) {
// ...
Statement statement= methodInvoker(method, test);
statement= possiblyExpectingExceptions(method, test, statement);
statement= withPotentialTimeout(method, test, statement);
statement= withBefores(method, test, statement);
statement= withAfters(method, test, statement);
statement= withRules(method, test, statement);
return statement;
}
JUnit 4.7 appears to stitch Statement chains together in a different order:
JUnit 4.7似乎以不同的顺序将Statement链接在一起:
Statement statement= methodInvoker(method, test);
statement= possiblyExpectingExceptions(method, test, statement);
statement= withPotentialTimeout(method, test, statement);
statement= withRules(method, test, statement);
statement= withBefores(method, test, statement);
statement= withAfters(method, test, statement);
return statement;
spring-test-3.0.5's parent POM seems to indicate that it depends on JUnit 4.7. I wonder if getting it to use a newer JUnit would help?
spring-test-3.0.5的父POM似乎表明它依赖于JUnit 4.7。我想知道是否使用更新的JUnit会有所帮助吗?
#2
0
For what it's worth, I've used the following as a quick workaround:
对于它的价值,我使用以下作为快速解决方法:
@Rule
public TemporaryFolder tmpFolder = new TemporaryFolder() {
@Override
protected void before() throws Throwable {
if (getRoot() == null) {
super.before();
}
}
@Override
public File newFile(String fileName) throws IOException {
try {
before();
}
catch (Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
return super.newFile(fileName);
}
@Override
public File newFolder(String folderName) {
try {
before();
}
catch (Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
return super.newFolder(folderName);
}
};
This ensures that the TemporaryFolder
is initialized properly, regardless of whether the @Before
methods are run before or after the rules.
这可确保正确初始化TemporaryFolder,无论@Before方法是在规则之前还是之后运行。
#1
12
In JUnit 4.10, BlockJUnit4ClassRunner (the superclass of SpringJUnit4ClassRunner) appears to take care to construct Statement chains in such a way that rules run before any @Before methods. From JUnit 4.10:
在JUnit 4.10中,BlockJUnit4ClassRunner(SpringJUnit4ClassRunner的超类)似乎注意构造Statement链,使得规则在任何@Before方法之前运行。从JUnit 4.10:
protected Statement methodBlock(FrameworkMethod method) {
// ...
Statement statement= methodInvoker(method, test);
statement= possiblyExpectingExceptions(method, test, statement);
statement= withPotentialTimeout(method, test, statement);
statement= withBefores(method, test, statement);
statement= withAfters(method, test, statement);
statement= withRules(method, test, statement);
return statement;
}
JUnit 4.7 appears to stitch Statement chains together in a different order:
JUnit 4.7似乎以不同的顺序将Statement链接在一起:
Statement statement= methodInvoker(method, test);
statement= possiblyExpectingExceptions(method, test, statement);
statement= withPotentialTimeout(method, test, statement);
statement= withRules(method, test, statement);
statement= withBefores(method, test, statement);
statement= withAfters(method, test, statement);
return statement;
spring-test-3.0.5's parent POM seems to indicate that it depends on JUnit 4.7. I wonder if getting it to use a newer JUnit would help?
spring-test-3.0.5的父POM似乎表明它依赖于JUnit 4.7。我想知道是否使用更新的JUnit会有所帮助吗?
#2
0
For what it's worth, I've used the following as a quick workaround:
对于它的价值,我使用以下作为快速解决方法:
@Rule
public TemporaryFolder tmpFolder = new TemporaryFolder() {
@Override
protected void before() throws Throwable {
if (getRoot() == null) {
super.before();
}
}
@Override
public File newFile(String fileName) throws IOException {
try {
before();
}
catch (Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
return super.newFile(fileName);
}
@Override
public File newFolder(String folderName) {
try {
before();
}
catch (Throwable t) {
throw new RuntimeException(t.getMessage(), t);
}
return super.newFolder(folderName);
}
};
This ensures that the TemporaryFolder
is initialized properly, regardless of whether the @Before
methods are run before or after the rules.
这可确保正确初始化TemporaryFolder,无论@Before方法是在规则之前还是之后运行。