当前位置: 首页 > 知识库问答 >
问题:

我需要帮助设置使用Spring、JUnit5、Mockito、REST-Assured和Lombok的控制器测试

郎祯
2023-03-14
@ExtendWith(MockitoExtension.class)
public class UserControllerTest extends TestAbstract {
    private final static String URI = "/user";

    @Mock
    private UserService userService;
    @InjectMocks
    private UserController userController;
    @InjectMocks
    private ControllerExceptionHandler controllerExceptionHandler;

    @BeforeEach
    public void initialiseRestAssuredMockMvcStandalone() {
        RestAssuredMockMvc.standaloneSetup(userController, controllerExceptionHandler);
    }
...
}

Maven Pom:

...
    <properties>
        <java.version>1.8</java.version>
        <junit-jupiter.version>5.6.2</junit-jupiter.version> <!--junit 5-->
        <mockito-junit-jupiter.version>3.4.3</mockito-junit-jupiter.version> <!--mockito for junit 5--> 
        <!--mockito ver 3.5.13 also attempted-->
        <spring-mock-mvc.version>3.3.0</spring-mock-mvc.version> <!--rest-assured-->
        <maven-surefire-plugin.version>2.22.0</maven-surefire-plugin.version>
    </properties>
...
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.mockito</groupId>
                    <artifactId>mockito-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
            <version>${mockito-junit-jupiter.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>spring-mock-mvc</artifactId>
            <version>${spring-mock-mvc.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
...

更新/更正

更正:UserControllerTest.java中的@beforeacter已更正为@beforeacter,这对于junit 5是正确的。

import static io.restassured.module.mockmvc.RestAssuredMockMvc.*
import static io.restassured.module.mockmvc.matcher.RestAssuredMockMvcMatchers.*
io.restassured.RestAssured.*
io.restassured.matcher.RestAssuredMatchers.*

共有1个答案

洪华皓
2023-03-14

这是控制器测试问题的解决方案。返回到JUnit4进行控制器测试。我的依赖关系不会改变,因为JUnit4可以在JUnit5中访问。

有趣的是,我发现我可以在集成测试和控制器测试中使用相同的放心代码。唯一的区别是控制器测试模拟服务层。因此,我有一个抽象父类UserControllerTestAbstract.java,它有两个子类UserControllerTest.java和UserIntegrationTest.java。

UserControllerTestAbstract.java(junit 5)

...
import org.junit.jupiter.api.Test;  // junit 5

import static io.restassured.module.mockmvc.RestAssuredMockMvc.given;
...

public abstract class UserControllerTestAbstract extends UserTestAbstract implements ControllerTestAbstract {
... // protected static final User variables ... for testing

    @Tag("positive")
    @Test
    public void whenAddUser_thenReturnsSuccessfulDefaultResponse() {
        // given a AddUserRequest
        AddUserRequest testAddUserRequest = AddUserRequest.builder()
                .user(testNewUser)
                .build();

        DefaultResponse foundDefaultResponse = given().log().all()
                .spec(requestSpec)
                .body(testAddUserRequest)

        // when addUser returns a Successful DefaultResponse
            .when()
                .post("/add")

        // then the JSON response is as expected
            .then().log().all()
                .spec(responseSpec)
                .extract().as(DefaultResponse.class);
        assertSuccessfulStatus(foundDefaultResponse); // custom assert method
    }
...
}

UserIntegrationTest.java(junit 5)

import org.junit.jupiter.api.Test; // junit 5
...

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
@Tag("integration-test")
public class UserIntegrationTest extends UserControllerTestAbstract {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @BeforeEach  // junit 5
    public void initialiseRestAssuredMockMvcWebApplicationContext() {
        RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
        RestAssuredMockMvc.basePath = "/user";
    }

    // The tests are in UserControllerTestAbstract and are used in the controller test as well.

    @Tag("negative")
    @Test
    @Disabled
    public void whenGetListOfAllUsers_thenReturnsErrorUserListResponse() {
        // This overrides and disables this integration test.
        // The test fails, because data.sql adds users to the DB.
        // To run this test, comment out all inserts to the users table in data.sql in both test and main resources.
        // Alternatively, you could rename data.sql in both test and main resources.
        // Then comment out @Disabled
        super.whenGetListOfAllUsers_thenReturnsErrorUserListResponse();
    }
}

到目前为止,只有一个测试需要被覆盖和禁用,因为它需要一个空的表来生成正确的响应。许多其他测试都期望填充该表。

UserControllerTest.java(junit 4)

import org.junit.Test; // junit 4
...

@RunWith(MockitoJUnitRunner.class)  // junit 4
@Tag("controller")
@Tag("unit-test")
public class UserControllerTest extends UserControllerTestAbstract {

    @Mock
    private UserService userService;
    @InjectMocks
    private UserController userController;
    @InjectMocks
    private ControllerExceptionHandler controllerExceptionHandler;

    @Before // junit 4
    public void initialiseRestAssuredMockMvcStandalone() {
        RestAssuredMockMvc.standaloneSetup(userController, controllerExceptionHandler);
        RestAssuredMockMvc.basePath = "/user";
    }

    @Tag("positive")
    @Test
    public void whenAddUser_thenReturnsSuccessfulDefaultResponse() {
        // given a User, a AddUserRequest and a DefaultResponse
        AddUserRequest testAddUserRequest = AddUserRequest.builder()
                .user(testNewUser)
                .build();
        DefaultResponse testDefaultResponse = new DefaultResponse();

        // when addUser returns a Successful DefaultResponse
        given(userService.addUser(any(AddUserRequest.class))).willReturn(testDefaultResponse);

        // then the JSON response is as expected
        super.whenAddUser_thenReturnsSuccessfulDefaultResponse();
    }
...
}
 类似资料:
  • 需要帮助使用Mockito和JUnit4为下面的代码编写单元测试,

  • 我有一个Spring Boot应用程序,想为控制器编写集成测试。它是我的: 它是我的控制器: 我创建了一个测试(JUnit5): 哪种方法更好?

  • 我有一个运行简单REST服务Spring Boot应用程序。我想测试一下这项服务。因为我喜欢Spock框架,所以我很愿意在这里使用它,但是我不能通过Spring配置的问题。 日志 例外情况

  • 你能帮我在jrxml中设置或更改哪些属性以获得相同的PDF输出吗?

  • 我已经从Godaddy购买了SSL,我的网站托管在AWS中。我想在AWS上设置SSL。我绑定使用证书管理器导入证书。它问了我三件事: 证书体*--在这里,我从Godaddy获得了。crt文件内容 证书私钥*--这里我仍然困惑需要输入什么。请帮我做这个 证书链--在这里我输入了sf_bundle-g2-g1.crt代码。 请帮助我启用AWS中的SSL。提前致谢

  • 我试图使用mockmvcbuilders.standalonesetup方法为一个spring mvc rest控制器创建一个非常基本的单元测试。我一直收到一个404错误。下面列出了测试应用程序上下文、测试类、控制器和整个堆栈跟踪。欢迎任何指导。 java.lang.AssertionError:状态应为:<200>但实际为:<404>在org.springframework.test.util.