优化单元测试
diff --git a/build.gradle b/build.gradle
index 0b1c3c0..a4cd5b1 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,11 +13,24 @@
         jcenter()
         mavenCentral()
     }
-    
+}
+
+ext {
+    set('junit_jupiter_version', "5.5.2")
+    set("junit_platform_version", "1.5.2")
+    set("mockitoVersion", "3.1.0")
 }
 
 subprojects {
+    apply plugin: 'java'
     version = '1.0'
+    dependencies {
+        testImplementation("org.junit.jupiter:junit-jupiter-api:${junit_jupiter_version}")
+        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junit_jupiter_version}")
+        testRuntimeOnly("org.junit.platform:junit-platform-launcher:${junit_platform_version}")
+        testImplementation("io.mockk:mockk:1.9.3")
+        testImplementation("org.hamcrest:hamcrest:2.1")
+    }
 }
 
 bootJar {
diff --git a/payapi-common/build.gradle b/payapi-common/build.gradle
index a1776a5..106d0ad 100644
--- a/payapi-common/build.gradle
+++ b/payapi-common/build.gradle
@@ -48,5 +48,4 @@
 
     implementation 'org.apache.commons:commons-lang3:3.9'
 
-    testImplementation 'junit:junit:4.12'
 }
\ No newline at end of file
diff --git a/payapi-common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java b/payapi-common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java
index 0b3dd8b..0a20a77 100644
--- a/payapi-common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java
+++ b/payapi-common/src/test/java/com/supwisdom/dlpay/api/bean/CitizenCardPayinitParamTest.java
@@ -1,25 +1,116 @@
 package com.supwisdom.dlpay.api.bean;
 
+import com.supwisdom.dlpay.api.annotation.*;
 import com.supwisdom.dlpay.api.types.IDTypes;
 import com.supwisdom.dlpay.api.types.SexTypes;
-import org.junit.Test;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
 
 import javax.validation.ConstraintViolation;
 import javax.validation.Validation;
 import javax.validation.Validator;
 import javax.validation.ValidatorFactory;
-import java.util.*;
+import java.util.List;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class CitizenCardPayinitParamTest {
 
   private Validator validator;
 
-  @org.junit.Before
+  @IDNoCheck(idno = "idno", idtype = "idtype", value = IDTypes.IDTYPE_LIST)
+  public static class TestBean {
+    @TransDate(message = "不是合法的交易日期")
+    private String transDate;
+    @TransTime(message = "不是合法的交易时间")
+    private String transTime;
+
+    @Sex
+    private String sex;
+
+    @MobileNumber
+    private String mobile;
+
+    private String valueList;
+
+    @UserStatus
+    private String status;
+
+    private String idtype;
+
+    private String idno;
+
+    public String getTransDate() {
+      return transDate;
+    }
+
+    public void setTransDate(String transDate) {
+      this.transDate = transDate;
+    }
+
+    public String getTransTime() {
+      return transTime;
+    }
+
+    public void setTransTime(String transTime) {
+      this.transTime = transTime;
+    }
+
+    public String getSex() {
+      return sex;
+    }
+
+    public void setSex(String sex) {
+      this.sex = sex;
+    }
+
+    public String getMobile() {
+      return mobile;
+    }
+
+    public void setMobile(String mobile) {
+      this.mobile = mobile;
+    }
+
+    public String getValueList() {
+      return valueList;
+    }
+
+    public void setValueList(String valueList) {
+      this.valueList = valueList;
+    }
+
+    public String getStatus() {
+      return status;
+    }
+
+    public void setStatus(String status) {
+      this.status = status;
+    }
+
+    public String getIdtype() {
+      return idtype;
+    }
+
+    public void setIdtype(String idtype) {
+      this.idtype = idtype;
+    }
+
+    public String getIdno() {
+      return idno;
+    }
+
+    public void setIdno(String idno) {
+      this.idno = idno;
+    }
+  }
+
+  @BeforeEach
   public void setUp() throws Exception {
     ValidatorFactory factor = Validation.buildDefaultValidatorFactory();
     validator = factor.getValidator();
@@ -31,7 +122,7 @@
 
     List<ConstraintViolation<CitizenCardPayinitParam>> violations = validate(param);
     String message = getViolationMessage(violations);
-    assertFalse(message, violations.isEmpty());
+    assertFalse(violations.isEmpty(), message);
   }
 
   private <T> List<ConstraintViolation<T>> validate(T param) {
@@ -53,17 +144,31 @@
   public void testOpenUserParam() {
     OpenUserParam param = new OpenUserParam();
     List<ConstraintViolation<OpenUserParam>> result = validate(param);
-    assertFalse(getViolationMessage(result), result.isEmpty());
+    assertFalse(result.isEmpty(), getViolationMessage(result));
 
     param.setIdtype(IDTypes.IDCARD.value());
-    param.setIdno("123213");
+    param.setIdno("123456789012345678");
     param.setUid("1231323");
     param.setName("lily");
     param.setSex(SexTypes.MALE.value());
     param.setMobile("+8618272733888");
 
     result = validate(param);
-    assertTrue(getViolationMessage(result), result.isEmpty());
+    assertTrue(result.isEmpty(), getViolationMessage(result));
+  }
 
+  @Test
+  void testCustomizeValidator() {
+    TestBean bean = new TestBean();
+    bean.setIdtype(IDTypes.IDCARD.value());
+    bean.setIdno("123456789012345678");
+    bean.setTransDate("20191001");
+    bean.setTransTime("135943");
+    bean.setMobile("+8618621110059");
+    bean.setSex("male");
+    bean.setStatus("open");
+
+    List<ConstraintViolation<TestBean>> result = validate(bean);
+    assertThat(getViolationMessage(result), result.isEmpty());
   }
 }
\ No newline at end of file
diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
index a964b02..baa1e34 100644
--- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
+++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/controller/user_api_controller.kt
@@ -42,20 +42,18 @@
     @PostMapping("/open")
     fun openAccount(@RequestBody param: OpenUserParam): ResponseEntity<Any> {
         try {
-            useService.findByThirdUniqueIdenty(param.uid).let {
-                if (null != it) {
-                    return ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .fail(TradeErrorCode.REGISTER_USER_EXIST, "该用户唯一号已经注册"))
-                }
+            useService.findByThirdUniqueIdenty(param.uid).takeIf { it != null }?.let {
+                return ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .fail(TradeErrorCode.REGISTER_USER_EXIST, "该用户唯一号已经注册"))
+            }
 
-                param.name = URLDecoder.decode(param.name, Charsets.UTF_8.toString()) //解码
-                param.address = param.address?.let { URLDecoder.decode(param.address, Charsets.UTF_8.toString()) }  //解码
-                useService.registerUser(param).let {
-                    return ResponseEntity.ok(ResponseBodyBuilder.create()
-                            .data("userid", it.userid)
-                            .data("uid", param.uid)
-                            .success())
-                }
+            param.name = URLDecoder.decode(param.name, Charsets.UTF_8.toString()) //解码
+            param.address = param.address?.let { URLDecoder.decode(param.address, Charsets.UTF_8.toString()) }  //解码
+            return useService.registerUser(param).let { person ->
+                ResponseEntity.ok(ResponseBodyBuilder.create()
+                        .data("userid", person.userid)
+                        .data("uid", param.uid)
+                        .success())
             }
         } catch (ex: RequestParamCheckException) {
             return ResponseEntity.ok(ResponseBodyBuilder.create()
diff --git a/payapi/src/test/kotlin/com/supwisdom/dlpay/MvcBaseTest.kt b/payapi/src/test/kotlin/com/supwisdom/dlpay/MvcBaseTest.kt
index 91bd2e1..99294c2 100644
--- a/payapi/src/test/kotlin/com/supwisdom/dlpay/MvcBaseTest.kt
+++ b/payapi/src/test/kotlin/com/supwisdom/dlpay/MvcBaseTest.kt
@@ -1,24 +1,25 @@
 package com.supwisdom.dlpay
 
 import com.google.gson.Gson
-import org.junit.runner.RunWith
+import org.junit.jupiter.api.BeforeEach
+import org.mockito.MockitoAnnotations
 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.ActiveProfiles
-import org.springframework.test.context.TestPropertySource
-import org.springframework.test.context.junit4.SpringRunner
 import org.springframework.test.web.servlet.MockMvc
 
 /**
  * mvc 基础测试类
  * 放置基础方法,如认证信息等
  */
-@RunWith(SpringRunner::class)
-@SpringBootTest
-@AutoConfigureMockMvc
-abstract class MvcBaseTest{
+//@RunWith(SpringRunner::class)
+//@SpringBootTest
+//@AutoConfigureMockMvc
+abstract class MvcBaseTest {
     @Autowired
     protected lateinit var mvc: MockMvc
     val gson = Gson()
+
+    @BeforeEach
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
 }
\ No newline at end of file
diff --git a/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/ApiControllerTest.kt b/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/ApiControllerTest.kt
index 01d6e50..672a074 100644
--- a/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/ApiControllerTest.kt
+++ b/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/ApiControllerTest.kt
@@ -1,9 +1,7 @@
 package com.supwisdom.dlpay.controller
 
 import com.supwisdom.dlpay.MvcBaseTest
-import com.supwisdom.dlpay.api.service.KafkaSendMsgService
 import org.junit.Test
-import org.springframework.beans.factory.annotation.Autowired
 import org.springframework.http.MediaType
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
 import org.springframework.test.web.servlet.result.MockMvcResultHandlers
diff --git a/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/UserControllerTest.kt b/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/UserControllerTest.kt
index c76eb14..d13dc34 100644
--- a/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/UserControllerTest.kt
+++ b/payapi/src/test/kotlin/com/supwisdom/dlpay/controller/UserControllerTest.kt
@@ -1,80 +1,139 @@
 package com.supwisdom.dlpay.controller
 
 import com.google.gson.Gson
-import com.supwisdom.dlpay.MvcBaseTest
 import com.supwisdom.dlpay.api.bean.OpenUserParam
 import com.supwisdom.dlpay.api.bean.QueryUserParam
+import com.supwisdom.dlpay.api.controller.UserAPIController
 import com.supwisdom.dlpay.api.domain.TAccount
 import com.supwisdom.dlpay.api.domain.TPerson
-import org.junit.Assert
-import org.junit.Test
+import com.supwisdom.dlpay.api.service.UserService
+import com.supwisdom.dlpay.framework.util.TradeErrorCode
+import io.mockk.MockKAnnotations
+import io.mockk.clearMocks
+import io.mockk.every
+import io.mockk.impl.annotations.InjectMockKs
+import io.mockk.impl.annotations.MockK
+import io.mockk.impl.annotations.RelaxedMockK
+import io.mockk.junit5.MockKExtension
+import io.mockk.verify
+import org.hamcrest.Matchers.`is`
+import org.hamcrest.Matchers.notNullValue
+import org.junit.jupiter.api.AfterEach
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
 import org.springframework.http.MediaType
+import org.springframework.test.web.servlet.MockMvc
 import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
-import org.springframework.test.web.servlet.result.MockMvcResultHandlers
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath
+import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
+import org.springframework.test.web.servlet.setup.MockMvcBuilders
 
 
-class UserControllerTest : MvcBaseTest() {
+@ExtendWith(MockKExtension::class)
+internal class UserControllerTest {
+    companion object {
+        const val thirdUID = "101010"
+    }
 
-    class RetBean {
-        var userid: String = ""
-        var retcode: Int = 0
-        lateinit var person: TPerson
-        lateinit var account: TAccount
+    @InjectMockKs
+    var userAPIController = UserAPIController()
+
+    lateinit var mockMvc: MockMvc
+
+    @MockK
+    lateinit var userService: UserService
+
+    private val person = TPerson().apply {
+        userid = "12312312213"
+    }
+
+    private fun singlePerson() = person
+
+    @BeforeEach
+    fun `context load`() {
+        mockMvc = MockMvcBuilders.standaloneSetup(userAPIController)
+                .build()
+        MockKAnnotations.init(this, relaxUnitFun = true)
+    }
+
+    @AfterEach
+    fun cleanup() {
+        clearMocks(userService)
     }
 
     @Test
-    fun open() {
+    fun `test open account error when thirdUID exists`() {
         val userParam = OpenUserParam()
-        userParam.uid = ""//random req
+        userParam.uid = thirdUID
         userParam.name = "测试名称"
 
-        val ret = mvc.perform(MockMvcRequestBuilders.post("/api/user/open").content(gson.toJson(userParam))
-                .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(MockMvcResultMatchers.status().isOk)
-                .andDo(MockMvcResultHandlers.print())
-                .andReturn()
-        val res = ret.response.contentAsString
-        Assert.assertNotNull(res)
-        val retBean = gson.fromJson(res, RetBean::class.java)
-        Assert.assertNotNull(retBean)
-        Assert.assertEquals(0, retBean.retcode)
-        Assert.assertNotNull(retBean.userid)
-        Assert.assertNotEquals("", retBean.userid)
+        every { userService.findByThirdUniqueIdenty(thirdUID) } returns singlePerson()
+        mockMvc.perform(MockMvcRequestBuilders.post("/api/user/open")
+                .contentType(MediaType.APPLICATION_JSON_UTF8)
+                .content(Gson().toJson(userParam)))
+                .andExpect(status().isOk)
+                .andExpect(jsonPath("$.retcode").value(TradeErrorCode.REGISTER_USER_EXIST))
+
+        verify(exactly = 1) { userService.findByThirdUniqueIdenty(thirdUID) }
     }
 
     @Test
-    fun get() {
+    fun `test open account success`() {
+        val userParam = OpenUserParam()
+        userParam.uid = thirdUID
+        userParam.name = "测试名称"
+        userParam.address = "上海市隆昌路619号8号楼"
 
-        val userParam = QueryUserParam()
-        userParam.uid = "testuseruniqueId"//测试用
-        val gson = Gson()
-        val ret = mvc.perform(MockMvcRequestBuilders.post("/api/user/open").content(gson.toJson(userParam))
-                .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(MockMvcResultMatchers.status().isOk)
-                .andDo(MockMvcResultHandlers.print())
-                .andReturn()
-        val resOpen = ret.response.contentAsString
-        Assert.assertNotNull(resOpen)
-        val retBeanOpen = gson.fromJson(resOpen, RetBean::class.java)
-        Assert.assertNotNull(retBeanOpen)
-        Assert.assertNotNull(retBeanOpen.userid)
-        userParam.userid = retBeanOpen.userid
+        every { userService.findByThirdUniqueIdenty(thirdUID) } returns null
+        every { userService.registerUser(any()) } returns singlePerson()
+        mockMvc.perform(MockMvcRequestBuilders.post("/api/user/open")
+                .contentType(MediaType.APPLICATION_JSON_UTF8)
+                .content(Gson().toJson(userParam)))
+                .andExpect(status().isOk)
+                .andExpect(jsonPath("$.retcode").value(0))
+                .andExpect(jsonPath("$.uid", notNullValue()))
+                .andExpect(jsonPath("$.userid").value(person.userid))
 
-        val retGet = mvc.perform(MockMvcRequestBuilders.get("/api/user/query").content(gson.toJson(userParam))
-                .contentType(MediaType.APPLICATION_JSON))
-                .andExpect(MockMvcResultMatchers.status().isOk)
-                .andDo(MockMvcResultHandlers.print())
-                .andReturn()
-        val res = retGet.response.contentAsString
-        Assert.assertNotNull(res)
-        val retBean = gson.fromJson(res, RetBean::class.java)
-        Assert.assertNotNull(retBean)
-        Assert.assertEquals(0, retBean.retcode)
-        Assert.assertNotNull(retBean.person)
-        Assert.assertEquals(retBeanOpen.userid, retBean.person.userid)
-        Assert.assertNotNull(retBeanOpen.account)
-        Assert.assertEquals(retBeanOpen.person.userid, retBean.account.userid)
+        verify(exactly = 1) { userService.findByThirdUniqueIdenty(thirdUID) }
+        verify(exactly = 1) { userService.registerUser(any()) }
     }
 
+    @Test
+    fun `test query account success`() {
+
+        val param = QueryUserParam().apply {
+            uid = thirdUID
+            userid = "1010101010"
+        }
+
+        val person = TPerson().apply {
+            userid = param.userid
+            name = "张三"
+            idtype = "idcard"
+            idno = "10101010101"
+            mobile = "1231231"
+            email = "ddlddl"
+            status = "1"
+        }
+        val account = TAccount().apply {
+            userid = param.userid
+            availbal = 10.0
+        }
+        every { userService.findByUseridOrThirdUniqueIdenty(param.userid, param.uid) } returns person
+        every { userService.findAccountByUserid(param.userid, null) } returns account
+        every { userService.findPointsAccountByUserid(param.userid) } returns null
+
+        mockMvc.perform(MockMvcRequestBuilders.post("/api/user/query")
+                .contentType(MediaType.APPLICATION_JSON_UTF8)
+                .content(Gson().toJson(param)))
+                .andExpect(status().isOk)
+                .andExpect(jsonPath("$.retcode", `is`(0)))
+                .andExpect(jsonPath("$.userid", `is`(param.userid)))
+                .andExpect(jsonPath("$.balance", `is`(10.0)))
+
+        verify(exactly = 1) { userService.findByUseridOrThirdUniqueIdenty(param.userid, param.uid) }
+        verify(exactly = 1) { userService.findAccountByUserid(param.userid, null) }
+        verify(exactly = 1) { userService.findPointsAccountByUserid(param.userid) }
+    }
 }
\ No newline at end of file
diff --git a/payapi/src/test/kotlin/com/supwisdom/dlpay/utils_test.kt b/payapi/src/test/kotlin/com/supwisdom/dlpay/utils_test.kt
index 33cba31..7c22f4c 100644
--- a/payapi/src/test/kotlin/com/supwisdom/dlpay/utils_test.kt
+++ b/payapi/src/test/kotlin/com/supwisdom/dlpay/utils_test.kt
@@ -8,6 +8,7 @@
     @Test
     fun testAgentResponse() {
         val response = AgentResponse<String>()
+        response.payload = "ok test"
         assertNotNull(response.payload)
     }
 }
\ No newline at end of file