JUnit: 如何避免在 test utils 类中出现“无法运行的方法”

我把 JUnit3.8换成了 JUnit4.4。我使用 ant 运行测试,所有测试都成功运行,但测试实用程序类失败,并出现“ No runnable method”错误。我使用的模式是在测试文件夹下包含名称为 * Test * 的所有类。

我知道运行程序找不到任何带有@Test 属性注释的方法。但是它们不包含这样的注释,因为这些类不是测试。 令人惊讶的是,当在 eclipse 中运行这些测试时,它并没有抱怨这些类。

在 JUnit3.8中,这根本不是问题,因为这些实用程序类没有扩展 TestCase,所以运行程序不会尝试执行它们。

我知道我可以在 ant 脚本的 junit 目标中排除这些特定的类。但是我不想在我添加的每个新实用程序类上更改构建文件。我也可以重命名类(但给类取好名字总是我最弱的天赋:)

这个问题有什么好的解决办法吗?

123119 次浏览

假设您控制了用于查找测试类的模式,我建议将其更改为匹配 *Test而不是 *Test*。这样 TestHelper不会被匹配,但 FooTest会。

What about adding an empty test method to these classes?

public void avoidAnnoyingErrorMessageWhenRunningTestsInAnt() {
assertTrue(true); // do nothing;
}

用@Ignore 注释 util 类,这会导致 JUnit 不尝试将它们作为测试运行。

我的具体案例有以下情况,我们的测试

public class VenueResourceContainerTest extends BaseTixContainerTest

all extend

BaseTixContainerTest

JUnit 试图运行 BaseTixContainerTest。可怜的 BaseTixContainerTest 只是试图设置容器,设置客户端,订购一些比萨饼和放松... 男人。

As mentioned previously, you can annotate the class with

@Ignore

但是,这导致 JUnit 将该测试报告为跳过(而不是完全忽略)。

Tests run: 4, Failures: 0, Errors: 0, Skipped: 1

这让我有点恼火。

So I made BaseTixContainerTest abstract, and now JUnit truly ignores it.

Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

要防止 JUnit 实例化您的测试基类,只需创建

public abstract class MyTestBaseClass { ... whatever... }

(@Ignore 将其报告为忽略,我将其保留给 暂时的忽略的测试。)

我也面临着类似的问题(“没有可运行的方法。.")运行最简单的代码片段(使用@Test,@Before 等) ,却找不到解决方案。我使用的是 Junit4和 Eclipse SDK 版本4.1.2。通过使用最新的 Eclipse SDK 4.2.2解决了我的问题。我希望这能帮助那些在类似问题上挣扎的人们。

Ant 现在提供了 skipNonTests属性,这个属性被设计用来完成您似乎正在寻找的任务。不需要将基类更改为抽象或添加注释。

Be careful when using an IDE's code-completion to add the import for @Test.

例如,它必须是 import org.junit.Test而不是 import org.testng.annotations.Test。如果执行后一种操作,则会得到“ no runnable method”错误。

  1. If this is your base test class for example AbstractTest and all your tests extends this then define this class as 摘要
  2. If it is Util class then better remove *Test from the class rename it is MyTestUtil or Utils etc.

在您的测试类中,如果编写 import org.junit.jupiter.api。测试; 删除它并编写 import org.junit。测试; 在这种情况下,它也起作用了。

我也曾遇到过同样的问题。在我的例子中,我使用 Junit 的封闭运行程序运行测试。我创建了一个名为 SharedSetup 的类,以便为我的2个测试类启用通用特性。但不知何故面临着同样的问题。

@RunWith(Enclosed.class)
public class StructApprovalNodeTest {


abstract static class SharedSetup {


StructApprovalNode sut;


ExecutionContext ctx = mock(ExecutionContext.class);
DTDDAOService dtd = mock(DTDDAOService.class);


@Rule
public ExpectedException expectedException = ExpectedException.none();


@Before
public void before() throws Exception {
PowerMockito.mockStatic(ServiceHelper.class);


when(ServiceHelper.getService("dtd")).thenReturn(dtd);
when(ctx.getContextInstance()).thenReturn(mock(ContextInstance.class));


when(dtd.getLatestStructures(Matchers.anyInt(), Matchers.anyString(), Matchers.anyString())).thenReturn(
new ArrayList<Trade>());


sut = new StructApprovalNode();
spy(sut);
}
}


@RunWith(PowerMockRunner.class)
@PrepareForTest({ ServiceHelper.class, StructApprovalNode.class })
@PowerMockIgnore("javax.management.*")
@PowerMockRunnerDelegate(Parameterized.class)
public static class ParamaterizedBatchTest extends SharedSetup {


private String batchName;
private String approvalStatus;


public ParamaterizedBatchTest(String batchName, String approvalStatus) {
this.batchName = batchName;
this.approvalStatus = approvalStatus;
}


@Parameterized.Parameters
public static Collection testValues() {
return Arrays.asList(new Object[][] {
{ "SDC_HK_AUTOMATION_BATCH", Constants.APRVLSTATUS_APPROVED },
{ "SDC_PB_AUTOMATION_BATCH", Constants.APRVLSTATUS_APPROVED },
{ "SDC_FX_AUTOMATION_BATCH", Constants.APRVLSTATUS_APPROVED }
});
}


@Test
public void test1_SDCBatchSourceSystems() throws Exception {
Trade trade = new Trade();
String tradeXml = FileHelper.getResourceFromJar("/testdata/SDC_BATCH_TRADE_XML.xml");
trade.setTradeXml(tradeXml);
trade.setTradeDoc(XmlHelper.createDocument(trade.getTradeXml()));
trade.setStatus(Constants.STATUS_LIVE);
trade.setSourceSystem(this.batchName);


when(ctx.getContextInstance().getVariable("trade")).thenReturn(trade);
when(ctx.getContextInstance().getTransientVariable("prevTrade")).thenReturn(null);


sut.execute(ctx);


PowerMockito.verifyPrivate(sut, times(1)).invoke("resetApprovalDetails", trade);
Assert.assertEquals(this.approvalStatus, trade.getApprovalStatus());
}


}


@RunWith(PowerMockRunner.class)
@PrepareForTest({ ServiceHelper.class, StructApprovalNode.class })
@PowerMockIgnore("javax.management.*")
public static class NonParamaterizedBatchTest extends SharedSetup {


@Test
public void test2_PrevInvalidTrade() throws Exception {
expectedException.expect(Exception.class);
expectedException.expectMessage("External Id of STRUCTURE_TRADE cannot be changed.");


Trade trade = new Trade();
trade.setExternalId(123);
PrevTrade prevTrade = new PrevTrade();
prevTrade.setExternalId(1234);


when(ctx.getContextInstance().getVariable("trade")).thenReturn(trade);
when(ctx.getContextInstance().getTransientVariable("prevTrade")).thenReturn(prevTrade);


sut.execute(ctx);
}


@Test
public void test3_ValidPrevTrade() throws Exception {
Trade trade = new Trade();
String tradeXml = FileHelper.getResourceFromJar("/testdata/SDC_BATCH_TRADE_XML.xml");
trade.setTradeXml(tradeXml);
trade.setTradeDoc(XmlHelper.createDocument(trade.getTradeXml()));
trade.setStatus(Constants.STATUS_LIVE);
trade.setSourceSystem("BATCH");
trade.setExternalId(1277402441);


PrevTrade prevTrade = new PrevTrade();
prevTrade.setExternalId(1277402441);


when(ctx.getContextInstance().getVariable("trade")).thenReturn(trade);
when(ctx.getContextInstance().getTransientVariable("prevTrade")).thenReturn(prevTrade);


sut.execute(ctx);


PowerMockito.verifyPrivate(sut, times(1)).invoke("resetApprovalDetails", trade);
Assert.assertEquals("APPROVED", trade.getApprovalStatus());
}


@Test
public void test4_ValidPrevTradeAutoApprpve() throws Exception {
Trade trade = new Trade();
String tradeXml = FileHelper.getResourceFromJar("/testdata/SDC_BATCH_TRADE_XML_AUTO_APPRV.xml");
trade.setTradeXml(tradeXml);
trade.setTradeDoc(XmlHelper.createDocument(trade.getTradeXml()));
trade.setStatus(Constants.STATUS_LIVE);
trade.setSourceSystem("BATCH");
trade.setExternalId(1277402441);


PrevTrade prevTrade = new PrevTrade();
prevTrade.setExternalId(1277402441);
prevTrade.setApprovalStatus(Constants.APRVLSTATUS_NOTAPPROVED);


when(ctx.getContextInstance().getVariable("trade")).thenReturn(trade);
when(ctx.getContextInstance().getTransientVariable("prevTrade")).thenReturn(prevTrade);


sut.execute(ctx);


PowerMockito.verifyPrivate(sut, times(1)).invoke("resetApprovalDetails", trade);
Assert.assertEquals(prevTrade.getApprovalStatus(), trade.getApprovalStatus());
}


@Test
public void test5_tradeStatusDraft() throws Exception {
Trade trade = new Trade();
String tradeXml = FileHelper.getResourceFromJar("/testdata/SDC_BATCH_TRADE_XML.xml");
trade.setTradeXml(tradeXml);
trade.setTradeDoc(XmlHelper.createDocument(trade.getTradeXml()));
trade.setStatus(Constants.STATUS_DRAFT);
trade.setSourceSystem("BATCH");
trade.setExternalId(1277402441);


when(ctx.getContextInstance().getVariable("trade")).thenReturn(trade);
when(ctx.getContextInstance().getTransientVariable("prevTrade")).thenReturn(null);


sut.execute(ctx);


PowerMockito.verifyPrivate(sut, times(1)).invoke("resetApprovalDetails", trade);
Assert.assertEquals(Constants.APRVLSTATUS_NONE, trade.getApprovalStatus());
}


}

}

为了解决这个问题,我只是从抽象超类 SharedSetup 中删除了 public 修饰符,问题就彻底解决了