我实现了一个JUnit 4 TestRule(扩展一个ExternalResource),并将其作为@ClassRule我的测试类注入:我想在这个类的每个测试中为所有资源初始化一次,并最终将其拆除.
我的问题是在我的方法之前/之后根本没有调用我的@Before和@After规则@Test方法:任何想法为什么会发生这种情况?
最小的可编辑示例:
package com.acme.test;
import static org.junit.Assert.assertNull;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;
class Coffee {
public void throwAway() {}
}
class CoffeeMachine extends ExternalResource {
Coffee whatElse;
@Override protected void before() throws Throwable {
whatElse = new Coffee();
}
@Override protected void after() {
whatElse.throwAway();
}
public Coffee gimmieCoffee() { return whatElse; }
}
public class CoffeeTester {
@ClassRule public static CoffeeMachine CM = …Run Code Online (Sandbox Code Playgroud) 如何在调用onCreate之前获取Activity的引用.而它的测试.我使用ActivityTestRule作为JUnit规则.这个要求的原因是我想从测试中将Mocks注入活动.
public class MyActivity extends Activity{
MyComponent myComponent;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if(myComponent==null){
myComponent ... //initialise dagger component
}
myComponent.inject(this);
...
}
public void setComponent(MyComponent comp){
this.myComponent = comp;
}
}
public class MyTest{
@Rule
public ActivityTestRule<MyActivity> intentsTestRule = new ActivityTestRule<>(MyActivity.class);
MyComponent myFakeComponent;
@Before
public void setUp() {
MyActivity activity = intentsTestRule.getActivity();
activity.setComponent(myFakeComponent);
}
@Test
public void testMethod1(){...}
}
Run Code Online (Sandbox Code Playgroud) I am transitioning from junit4 to junit5 on a project and trying to figure out how to test logs. Previously, I used
@Rule
OutputCapture outputCapture = new OutputCapture();
Run Code Online (Sandbox Code Playgroud)
and would then write an assertion using outputCapture.toString(), for example
assertThat(outputCapture.toString(),containsString("status=200"));
Since @Rule annotation hasn't been implemented yet in junit5, I can't use outputCapture. Any ideas what to do instead? Thanks!
我想创建一个代表这种树的baseFolder的JUnit TemporyFolder:
baseFolder/subFolderA/subSubFolder
/subFolderB/file1.txt
Run Code Online (Sandbox Code Playgroud)
据我所知,我可以设置一个TemporaryFolder,而不是可以创建位于该文件夹中的"newFolder()"伪文件夹.但是如何在下面创建图层?特别是在测试后清理的方式.
我想测试异常的返回码.这是我的生产代码:
class A {
try {
something...
}
catch (Exception e)
{
throw new MyExceptionClass(INTERNAL_ERROR_CODE, e);
}
}
Run Code Online (Sandbox Code Playgroud)
和相应的例外:
class MyExceptionClass extends ... {
private errorCode;
public MyExceptionClass(int errorCode){
this.errorCode = errorCode;
}
public getErrorCode(){
return this.errorCode;
}
}
Run Code Online (Sandbox Code Playgroud)
我的单元测试:
public class AUnitTests{
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test (expected = MyExceptionClass.class,
public void whenRunningSomething_shouldThrowMyExceptionWithInternalErrorCode() throws Exception {
thrown.expect(MyExceptionClass.class);
??? expected return code INTERNAL_ERROR_CODE ???
something();
}
}
Run Code Online (Sandbox Code Playgroud) 我想重用一些集成测试来进行负载测试.我实现了一个由注释参数化的规则:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {
int invocations() default 1;
int rampUpTime() default 0;
}
Run Code Online (Sandbox Code Playgroud)
在我的规则实现中,评估注释并设置一个语句,该语句具有如下的evaluate方法:
@Override
public void evaluate() throws Throwable {
ScheduledExecutorService exe = Executors.newScheduledThreadPool(invocations);
for (int i = 0; i < invocations; i++) {
ScheduledFuture<?> scheduledFuture = exe.schedule(new Runnable() {
@Override
public void run() {
try {
invocated++;
// Request test = Request.method(description.getTestClass(), description.getMethodName());
// new JUnitCore().run(test);
statement.evaluate();
} catch (Throwable e) {
e.printStackTrace();
}
}
}, i * rampUpTime, this.timeUnit);
futures.add(scheduledFuture);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,evaluate …
根据PowerMock文档,我应该能够使用a PowerMockRule而不是@RunWith(PowerMockRunner.class)得到相同的结果.
我似乎找到了一个不存在这种情况的案例.
以下示例运行良好:
package com.test.powermockstatics;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
final class FinalClassWithStaticCall {
public static int getIntStatic() {
return 1;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(FinalClassWithStaticCall.class)
public class TestStaticMockingWithoutPowerMockRunner {
@Test
public void testStaticCall() {
mockStatic(FinalClassWithStaticCall.class);
when(FinalClassWithStaticCall.getIntStatic()).thenReturn(2);
assertEquals(FinalClassWithStaticCall.getIntStatic(), 2);
}
}
Run Code Online (Sandbox Code Playgroud)
但是当切换到这样的规则时:
package com.test.powermockstatics;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import org.junit.Rule;
import org.junit.Test;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.agent.PowerMockAgent;
import org.powermock.modules.junit4.rule.PowerMockRule; …Run Code Online (Sandbox Code Playgroud) 在更复杂的单元测试中,我经常需要存在一组特定的规则。其中一些规则与另一个规则有依赖关系。由于排序是相关的,因此我使用 RuleChains。到目前为止一切都很好。
然而,这在大多数测试中都是重复的(偶尔会使用附加规则)。这种重复不仅感觉没有必要,重复起来也很麻烦,而且很多地方都需要调整,什么时候应该集成一个额外的Rule。
我想要的是规则规则,即包含或聚合其他(特定于应用程序和测试的)规则的(预定义)规则。
我将举例说明目前的情况:
public LoggingRule logRule = new LogRule();
public ConfigurationRule configurationRule = new ConfigurationRule();
public DatabaseConnectionRule dbRule = new DatabaseConnectionRule();
public ApplicationSpecificRule appRule = new ApplicationSpecificRule();
@Rule
RuleChain chain = RuleChain.outerRule(logRule)
.around(configurationRule)
.around(dbRule)
.around(appRule);
Run Code Online (Sandbox Code Playgroud)
假设给定的规则相互依赖,例如 ApplicationSpecificRule 要求首先执行 DatabaseConnectionRule 以建立连接,ConfigurationRule 已经初始化了一个空配置等。还假设对于这个(相当复杂的测试)所有规则都是实际需要。
到目前为止,我能想到的唯一解决方案是创建返回预定义 RuleChain 的工厂方法:
public class ApplicationSpecificRule extends ExternalResource
{
public static RuleChain basicSet()
{
return RuleChain.outerRule(new LogRule())
.around(new ConfigurationRule())
.around(new DatabaseConnectionRule())
.around(new ApplicationSpecificRule());
}
}
Run Code Online (Sandbox Code Playgroud)
在测试中,这可以按如下方式使用:
@Rule
RuleChain chain = ApplicationSpecificRule.basicSet();
Run Code Online (Sandbox Code Playgroud)
这样就消除了重复,并且可以轻松集成其他规则。甚至可以向该规则链添加特定于测试的规则。但是,当需要进行额外设置时,您无法访问包含的规则(假设您需要ApplicationSpecificRule为了创建某些域对象等)。
理想情况下,这将扩展为还支持使用其他预定义的集合,例如 …
我想要一个简单的方法为我的JUnit测试分配一个优先级值,这样我就可以说'只运行优先级1测试','运行优先级1,2和3测试'等等.我知道我可以只包括一行就像Assume.assumeTrue("Test skipped for priority " + priority, priority <= 2);在每个测试(其中的开始priority是最高值优先测试,我想运行,并2为这个特殊的测试的优先级值),但是复制粘贴在每个测试的开始行似乎没有一个很好的解决方案.
我尝试使用一个简单的注释编写解决方案,该注释由我正在使用的JUnit规则检测:
public class Tests {
@Rule
public TestRules rules = new TestRules();
@Test
@Priority(2)
public void test1() {
// perform test
}
}
public class TestRules extends TestWatcher {
private int priority = 1; // this value is manually changed to set the priority of tests to run
@Override
protected void starting(Description desc) {
Priority testCasePriority = desc.getAnnotation(Priority.class);
Assume.assumeTrue("Test skipped for priotity " + …Run Code Online (Sandbox Code Playgroud) 以下代码段足以重现我的问题:
thrown属性public并获取错误org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public fieldpublic修饰符并获取错误org.junit.internal.runners.rules.ValidationError: The @Rule 'thrown' must be public.public修饰符到位并@Dependent在类上添加注释范围,但是出现了错误org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public @Dependent @ApplicationScoped @RunWith我删除了所有不必要的代码,但这是一个非常复杂的单元测试,通过CDI进行模拟,服务注入,并且一些测试方法预计会引发异常.
import org.jglue.cdiunit.CdiRunner;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
@RunWith(CdiRunner.class)
public class FooBarTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void test() {
}
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,一方面Weld希望所有字段都不公开,因为否则它将无法代理该类,另一方面,JUnit希望规则字段是公共的,因为它使用反射来访问它们setAccessible(true)由于安全管理器处于活动状态,因此不希望使用该方法.如何处理这个悖论? …
junit-rule ×10
java ×8
junit ×7
junit4 ×2
android ×1
cdi ×1
cdi-unit ×1
junit-runner ×1
junit5 ×1
logging ×1
mocking ×1
mockito ×1
powermock ×1
testing ×1
unit-testing ×1