我有一个类似于这个的简单注释控制器:
@Controller
public class MyController {
@RequestMapping("/{id}.html")
public String doSomething(@PathVariable String id, Model model) {
// do something
return "view";
}
}
Run Code Online (Sandbox Code Playgroud)
我想用这样的单元测试来测试它:
public class MyControllerTest {
@Test
public void test() {
MockHttpServletRequest request = new MockHttpServletRequest();
request.setRequestURI("/test.html");
new AnnotationMethodHandlerAdapter()
.handle(request, new MockHttpServletResponse(), new MyController());
// assert something
}
}
Run Code Online (Sandbox Code Playgroud)
问题是AnnotationMethodHandlerAdapter.handler()方法抛出异常:
java.lang.IllegalStateException: Could not find @PathVariable [id] in @RequestMapping
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.resolvePathVariable(AnnotationMethodHandlerAdapter.java:642)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolvePathVariable(HandlerMethodInvoker.java:514)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:262)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:146)
Run Code Online (Sandbox Code Playgroud) 据我所知,TestExecutionListeners就像@BeforeClassJUnit中的方法一样.我不明白的是为什么我需要使用DependencyInjectionTestExecutionListener,TransactionalTestExecutionListener而DirtiesContextTestExecutionListener使用DbUnitTestExecutionListener.
通常没有DbUnit,我可以创建并填充数据库.为什么我突然需要使用这些监听器CRUD为我的数据库做一些事情?
我有测试导致错误.我试图在IntelliJ Idea中执行它2018.3.2.所有jupiter和junit依赖项都有版本RELEASE
错误全文:
Dec 26, 2018 1:17:17 AM org.junit.platform.launcher.core.DefaultLauncher handleThrowable
WARNING: TestEngine with ID 'junit-jupiter' failed to execute tests
java.lang.NoSuchMethodError: org.junit.platform.commons.util.ReflectionUtils.tryToLoadClass(Ljava/lang/String;)Lorg/junit/platform/commons/function/Try;
at org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector.createAbortedExecutionPredicate(OpenTest4JAndJUnit4AwareThrowableCollector.java:40)
at org.junit.jupiter.engine.support.OpenTest4JAndJUnit4AwareThrowableCollector.<clinit>(OpenTest4JAndJUnit4AwareThrowableCollector.java:30)
at org.junit.jupiter.engine.support.JupiterThrowableCollectorFactory.createThrowableCollector(JupiterThrowableCollectorFactory.java:34)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:68)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Run Code Online (Sandbox Code Playgroud)
测试有以下观点
import biz.Services.msg.BookTimeMsgService;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertTrue;
@ExtendWith(MockitoExtension.class)
public class MsgReceiverTest {
@Mock
BookTimeMsgService bookTimeMsgService; …Run Code Online (Sandbox Code Playgroud) 我正在尝试结合以下注释:
org.springframework.test.context.jdbc.Sql 和 org.junit.Before
像下面的代码:
@Test
@Sql(scripts = "dml-parametro.sql")
public void testData(){
Iterable<Parametro> parametros = parametroService.findAll();
List<Parametro> parametrosList = Lists.newArrayList(parametros);
Assert.assertThat(parametrosList.size(), Is.is(1));
}
@Before
public void beforeMethod() {
JdbcTestUtils.deleteFromTables(jdbcTemplate, "PARAMETRO");
}
Run Code Online (Sandbox Code Playgroud)
方法@Before中的代码在@Sql批注中的脚本"dml-parametro.sql"之后运行.
这样做是对的吗?
为了解决这个问题,我使用@After而不是@Before,但是我想在测试执行之前而不是之后删除表.
我不想使用@SqlConfig.我没有在测试级别上使用transacional scope,所以我需要在每个测试方法中清理我的表.如果每个测试方法都需要清理表,我想在@Before方法中执行此操作.我不想在每个使用@SqlConfig的测试方法中都这样做.我认为@Sql在@Before之前执行的行为是错误的.
我已经使用ExpectedException功能设置了一些JUnit(4.12)测试,我希望测试在预期的异常之后继续.但是我从来没有看到日志'3',因为执行似乎在异常后停止,如果捕获事件?
这实际上是可能的,怎么样?
@Rule
public ExpectedException exception = ExpectedException.none();
@Test
public void testUserAlreadyExists() throws Exception {
log.info("1");
// Create some users
userService.createUser("toto1");
userService.createUser("toto2");
userService.createUser("toto3");
Assert.assertTrue( userService.userExists("toto1") );
Assert.assertTrue( userService.userExists("toto2") );
Assert.assertTrue( userService.userExists("toto3") );
log.info("2");
// Try to create an existing user
exception.expect(AlreadyExistsException.class);
userService.createUser("toto1");
log.info("3");
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用JUnit5创建测试套件.经过一些研究后,我无法断定它是否是受支持的功能.
该官方用户指南,只提到套房关于向后兼容的JUnit 4.
这是在JUnit 4中完成的:
@RunWith(Suite.class)
@SuiteClasses({Test1.class, Test2.class})
public class TestSuite {
}
Run Code Online (Sandbox Code Playgroud)
这是否意味着,测试套件现在被视为已弃用,或者是否仍以其他名称提供相同的概念?
我已经在我的项目中使用AssertJ一段时间了.最近我开始使用Spring MVC Test来测试Spring MVC控制器.
但是我没有得到如何使用AssertJ.我在网上看到的所有例子都使用Hamcrest和Spring MVC Test.
下面是使用Hamcrest API的示例.
mockMvc
.perform(get("/user?operation=userList"))
.andExpect(status().isOk())
.andExpect(model().attribute(UserController.MODEL_ATTRIBUTE_USER_LIST, userList))
.andExpect(view().name(UserController.VIEW_USER_LIST))
.andExpect(model().attribute(UserController.MODEL_ATTRIBUTE_USER_LIST, hasSize(2)))
.andExpect(model().attribute(UserController.MODEL_ATTRIBUTE_USER_LIST, hasItem(
allOf(
hasProperty("id", is(1L)),
hasProperty("description", is("Lorem ipsum")),
hasProperty("title", is("Foo"))
)
)))
.andExpect(model().attribute(UserController.MODEL_ATTRIBUTE_USER_LIST, hasItem(
allOf(
hasProperty("id", is(2L)),
hasProperty("description", is("Lorem ipsum")),
hasProperty("title", is("Bar"))
)
)));
Run Code Online (Sandbox Code Playgroud) 我们有很多使用Spring的集成测试.我们不想为每个测试创建单独的JVM进程(maxParallelForks选项)或仅在多模块项目(--parallel)中运行并行构建.
我们希望单个测试类在Maven中并行执行测试,如http://maven.apache.org/surefire/maven-surefire-plugin/examples/fork-options-and-parallel-execution.html和并行测试选项
使用parallel选项时要记住的重要事项是:并发发生在同一个JVM进程中.
是否可以在Gradle中实现?
我MyTest在我的Spring集成测试中有一个特定的类(比方说),它@PrepareForTest在Spring组件上使用PowerMock 注释:@PrepareForTest(MyComponent.class).这意味着PowerMock将通过一些修改加载此类.问题是,我@ContextConfiguration是在扩展的超类上定义的MyTest,并且ApplicationContext是在不同的测试类之间缓存的.现在,如果MyTest先运行,它将具有正确的PowerMock版本MyComponent,但如果没有 - 测试将失败,因为上下文将被加载以进行另一次测试(没有@PrepareForTest).
所以我想要做的是重新加载我的上下文MyTest.我可以通过这样做
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS)
Run Code Online (Sandbox Code Playgroud)
但是,如果我还想在完成此测试后重新加载上下文怎么办?所以我会在MyComponent没有PowerMock修改的情况下再次清理.有没有办法做到既BEFORE_CLASS和AFTER_CLASS?
现在我用以下黑客做到了:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
Run Code Online (Sandbox Code Playgroud)
在MyTest然后
/**
* Stub test to reload ApplicationContext before execution of real test methods of this class.
*/
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
@Test
public void aa() {
}
/**
* Stub test to reload ApplicationContext after execution of real test methods of this class.
*/
@DirtiesContext(methodMode …Run Code Online (Sandbox Code Playgroud) tl;dr:如何在所有测试运行之前将自定义数据提供程序实例化为 Spring 组件?
是否有一种聪明的方法可以将 Spring 组件注入到实现 的自定义 JUnit Jupiter 扩展中BeforeAllCallback?该beforeAll方法应该在MyTestClass执行之前触发一个复杂的过程@ExtendWith(OncePerTestRunExtension.class)。
我创建了一个 Spring Boot 应用程序 ( src/main/java),它为我的测试 ( src/test/java) 提供了必要的数据。为测试准备数据可能需要长达几个小时的时间。它还使我可以抽象访问一些休息端点。
在所有测试类的过程之间,数据不会改变。所以我只想提取一次数据。
只在一个类中编写所有测试是可行的,但我认为分成不同的类可以提供更好的概览。
java ×7
spring-test ×6
spring ×4
junit5 ×3
junit ×2
spring-mvc ×2
unit-testing ×2
assertj ×1
dependencies ×1
gradle ×1
hamcrest ×1
junit-rule ×1
junit4 ×1
spring-boot ×1
test-suite ×1
testing ×1