【问题标题】:Junit Mockito how to pass user object to test methodJunit Mockito如何将用户对象传递给测试方法
【发布时间】:2018-02-16 07:52:44
【问题描述】:

我们有一个 Spring Rest 控制器,它接受一个带有(Authenticated 注释)和几个其他参数的 User 对象。你能告诉我们如何在 JUnit 测试方法中传递这个用户对象吗?我们试图在测试方法中如下调用,但低于异常堆栈跟踪。

测试调用:

mockMvc.perform(get("/test1/test2/test3/test4")
    .with(SecurityMockMvcRequestPostProcessors.user(new UsrHelpr().create()))
    .accept(MediaType.APPLICATION_JSON)
    .param("name", "testting"))
    .andExpect(status().isOk()).andReturn();

堆栈跟踪:

java.lang.AssertionError: Status expected:<200> but was:<400>
    at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
    at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
    at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
    <<The line number is the code I have pasted above in the test class >>
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

【问题讨论】:

  • 嗨,我已经用正确的参数重新运行了测试方法:如下: mockMvc.perform(get("/provision/warehouse/user/request") .with(SecurityMockMvcRequestPostProcessors.user(new UserHelper().create())).accept(MediaType.APPLICATION_JSON).param("status", "test")).andExpect(status().isOk()).andReturn();
  • 上述方式运行成功,但是当我们在调试模式下检查时,用户对象被传递为空。请告诉我们如何在测试方法中传递用户对象。
  • 我建议您在问题中添加这些 cmets,以便他们可以轻松阅读。

标签: spring junit


【解决方案1】:

在您的情况下,只需将用户对象作为参数值传递给模拟 mvc 请求,如下所示:

package com.example.stackoverflowsecurityissue;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class TestController {

    @RequestMapping(value = "/request", method = RequestMethod.GET)
    public ResponseEntity getMyRequests(MyUser user, @RequestParam(value = "status", required = true) String status) throws Exception {
        System.out.println(" user recevied " + user.toString());
        return ResponseEntity.ok().build();


    }

    protected static class MyUser {

        private String userName;

        private String password;

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        public MyUser(String userName) {
            this.userName = userName;
        }

        public MyUser(String userName, String password) {
            this.userName = userName;
            this.password = password;
        }

        @Override
        public String toString() {
            return "MyUser{" +
                    "userName='" + userName + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }

        public MyUser() {
        }

    }
}

我的控制器测试:

package com.example.stackoverflowsecurityissue;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilder;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class StackoverflowSecurityIssueApplicationTests {

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void performGetReq() throws Exception {
        ObjectMapper mapper=new ObjectMapper();
        mockMvc.perform(get("/request").
                param("userName","hello").param("password","hello").param("status","hello")).andExpect(status().isOk());
    }

}

输出:

 user recevied MyUser{userName='hello', password='hello'}

【讨论】:

  • 我们想要传递自定义的用户对象(我的用户类实现了 UserDetails ..e.g: public class User extends BaseEntity implements UserDetails。所以我有一个如下的帮助类(以下参考:stackoverflow.com/questions/360520/…)帮助类:@987654327 @
  • 将自定义对象作为模拟 mvc 请求的一部分传递?然后使用 .content(requestJson))?否则请更新您的控制器处理程序方法和安全配置的问题以获得更多帮助
  • 我们正在使用 SAML sso 安全性,示例控制器处理程序方法如下所示:@ApiOperation(value = "this is to get requests", response = Response.class) @RequestMapping(value = "/request", method = RequestMethod.GET) public Response&lt;List&lt;Request&gt;&gt; getMyRequests(@Authenticated MyUser user, @RequestParam(value = "status", required = true) String status) throws Exception { List&lt;Request&gt; requests = myService.getUserRequestByStatus(user.getMyid(), status); return new Response&lt;List&lt;Request&gt;&gt;(Response.STATUS_SUCCESS, requests); }
  • 我们如何在这里从 junit 测试方法传递 MyUser 类对象:请告诉我们mockMvc.perform(get("/test1/test2/test3/test4") .with(SecurityMockMvcRequestPostProcessors.user(new UsrHelpr().create())) .accept(MediaType.APPLICATION_JSON) .param("name", "testting")) .andExpect(status().isOk()).andReturn();
  • 这是我创建的要点。请通过gist.github.com/59082f4f2b8a02d40c64937b17cbda95.git。还更新了答案。但是我不知道@Authenticated 做什么,所以让它相应地工作
猜你喜欢
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2017-01-14
  • 2021-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多