#8 demetrm - complete

開啟中
demetrm 請求將 2 次程式碼提交從 demetrm/CR-MesoLab-Spring-PersonController.CRUD:master 合併至 master

+ 17
- 5
pom.xml 查看文件

14
 	<parent>
14
 	<parent>
15
 		<groupId>org.springframework.boot</groupId>
15
 		<groupId>org.springframework.boot</groupId>
16
 		<artifactId>spring-boot-starter-parent</artifactId>
16
 		<artifactId>spring-boot-starter-parent</artifactId>
17
-		<version>1.5.2.RELEASE</version>
18
-		<relativePath/> <!-- lookup parent from repository -->
17
+		<version>1.5.18.RELEASE</version>
19
 	</parent>
18
 	</parent>
20
 
19
 
21
 	<properties>
20
 	<properties>
31
 		</dependency>
30
 		</dependency>
32
 
31
 
33
 		<dependency>
32
 		<dependency>
34
-			<groupId>com.h2database</groupId>
35
-			<artifactId>h2</artifactId>
36
-            <scope>compile</scope>
33
+			<groupId>mysql</groupId>
34
+			<artifactId>mysql-connector-java</artifactId>
37
 		</dependency>
35
 		</dependency>
36
+
38
 		<dependency>
37
 		<dependency>
39
 			<groupId>org.springframework.boot</groupId>
38
 			<groupId>org.springframework.boot</groupId>
40
 			<artifactId>spring-boot-starter-test</artifactId>
39
 			<artifactId>spring-boot-starter-test</artifactId>
50
 			<artifactId>spring-boot-starter-data-jpa</artifactId>
49
 			<artifactId>spring-boot-starter-data-jpa</artifactId>
51
 			<!--<version>1.3.5.RELEASE</version>-->
50
 			<!--<version>1.3.5.RELEASE</version>-->
52
 		</dependency>
51
 		</dependency>
52
+        <dependency>
53
+            <groupId>org.mockito</groupId>
54
+            <artifactId>mockito-core</artifactId>
55
+            <version>1.10.19</version>
56
+            <exclusions>
57
+                <exclusion>
58
+                    <groupId>org.hamcrest</groupId>
59
+                    <artifactId>hamcrest-core</artifactId>
60
+                </exclusion>
61
+            </exclusions>
62
+            <scope>test</scope>
63
+        </dependency>
64
+
53
     </dependencies>
65
     </dependencies>
54
 
66
 
55
 	<build>
67
 	<build>

+ 6
- 9
src/main/java/io/zipcoder/crudapp/CRUDApplication.java 查看文件

1
 package io.zipcoder.crudapp;
1
 package io.zipcoder.crudapp;
2
 
2
 
3
-import org.h2.server.web.WebServlet;
4
 import org.springframework.boot.SpringApplication;
3
 import org.springframework.boot.SpringApplication;
5
 import org.springframework.boot.autoconfigure.SpringBootApplication;
4
 import org.springframework.boot.autoconfigure.SpringBootApplication;
6
-import org.springframework.boot.web.servlet.ServletRegistrationBean;
7
-import org.springframework.context.annotation.Bean;
8
 
5
 
9
 @SpringBootApplication
6
 @SpringBootApplication
10
 public class CRUDApplication {
7
 public class CRUDApplication {
13
 		SpringApplication.run(CRUDApplication.class, args);
10
 		SpringApplication.run(CRUDApplication.class, args);
14
 	}
11
 	}
15
 
12
 
16
-	@Bean
17
-	ServletRegistrationBean h2servletRegistration(){
18
-		ServletRegistrationBean registrationBean = new ServletRegistrationBean( new WebServlet());
19
-		registrationBean.addUrlMappings("/console/*");
20
-		return registrationBean;
21
-	}
13
+//	@Bean
14
+//	ServletRegistrationBean h2servletRegistration(){
15
+//		ServletRegistrationBean registrationBean = new ServletRegistrationBean( new WebServlet());
16
+//		registrationBean.addUrlMappings("/console/*");
17
+//		return registrationBean;
18
+//	}
22
 }
19
 }

+ 46
- 0
src/main/java/io/zipcoder/crudapp/controllers/PersonController.java 查看文件

1
+package io.zipcoder.crudapp.controllers;
2
+
3
+import io.zipcoder.crudapp.models.Person;
4
+import io.zipcoder.crudapp.services.PersonService;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.http.HttpStatus;
7
+import org.springframework.http.ResponseEntity;
8
+import org.springframework.web.bind.annotation.*;
9
+
10
+@RestController
11
+public class PersonController {
12
+
13
+    @Autowired
14
+    PersonService personService;
15
+
16
+    @RequestMapping(value = "/people", method = RequestMethod.GET)
17
+    public ResponseEntity<Iterable<Person>> getPersonList(){
18
+        Iterable<Person> people = personService.getPersonList();
19
+        return new ResponseEntity<>(people, HttpStatus.OK);
20
+    }
21
+
22
+    @RequestMapping(value = "/people/{id}", method = RequestMethod.GET)
23
+    public ResponseEntity<?> getPersonById(@PathVariable Long id){
24
+        Person p = personService.getPersonById(id);
25
+        if (p != null) return new ResponseEntity<>(p,HttpStatus.OK);
26
+        return new ResponseEntity<>(HttpStatus.NOT_FOUND);
27
+    }
28
+
29
+    @RequestMapping(value = "/people", method = RequestMethod.POST)
30
+    public ResponseEntity<?> createPerson(@RequestBody Person person){
31
+        Person p = personService.savePerson(person);
32
+        return new ResponseEntity<>(p, HttpStatus.CREATED);
33
+    }
34
+
35
+    @RequestMapping(value = "/people/{id}", method = RequestMethod.PUT)
36
+    public ResponseEntity<?> updatePerson(@PathVariable Long id, @RequestBody Person person){
37
+        Person p = personService.savePerson(person);
38
+        return new ResponseEntity<>(p,HttpStatus.OK);
39
+    }
40
+
41
+    @RequestMapping(value = "/people/{id}", method = RequestMethod.DELETE)
42
+    public ResponseEntity<Void> deletePerson(@PathVariable Long id){
43
+        personService.deletePerson(id);
44
+        return new ResponseEntity(HttpStatus.NO_CONTENT);
45
+    }
46
+}

+ 60
- 0
src/main/java/io/zipcoder/crudapp/models/Person.java 查看文件

1
+package io.zipcoder.crudapp.models;
2
+
3
+import javax.persistence.*;
4
+
5
+@Entity
6
+public class Person {
7
+
8
+    @Id
9
+    @GeneratedValue(strategy = GenerationType.AUTO)
10
+    @Column(name = "ID")
11
+    Long id;
12
+
13
+    @Column(name = "FIRST_NAME")
14
+    String firstName;
15
+
16
+    @Column(name = "LAST_NAME")
17
+    String lastName;
18
+
19
+    public Person() {
20
+    }
21
+
22
+    public Person(String firstName, String lastName) {
23
+        this.firstName = firstName;
24
+        this.lastName = lastName;
25
+    }
26
+
27
+    public Long getId() {
28
+        return id;
29
+    }
30
+
31
+    public String getFirstName() {
32
+        return firstName;
33
+    }
34
+
35
+    public void setFirstName(String firstName) {
36
+        this.firstName = firstName;
37
+    }
38
+
39
+    public String getLastName() {
40
+        return lastName;
41
+    }
42
+
43
+    public void setLastName(String lastName) {
44
+        this.lastName = lastName;
45
+    }
46
+
47
+    @Override
48
+    public boolean equals(Object o) {
49
+        return toString().equals(o.toString());
50
+    }
51
+
52
+    @Override
53
+    public String toString() {
54
+        return "Person{" +
55
+                "id=" + id +
56
+                ", firstName='" + firstName + '\'' +
57
+                ", lastName='" + lastName + '\'' +
58
+                '}';
59
+    }
60
+}

+ 10
- 0
src/main/java/io/zipcoder/crudapp/repositories/PersonRepository.java 查看文件

1
+package io.zipcoder.crudapp.repositories;
2
+
3
+import io.zipcoder.crudapp.models.Person;
4
+import org.springframework.data.repository.CrudRepository;
5
+import org.springframework.stereotype.Repository;
6
+
7
+@Repository
8
+public interface PersonRepository extends CrudRepository<Person, Long> {
9
+
10
+}

+ 29
- 0
src/main/java/io/zipcoder/crudapp/services/PersonService.java 查看文件

1
+package io.zipcoder.crudapp.services;
2
+
3
+import io.zipcoder.crudapp.models.Person;
4
+import io.zipcoder.crudapp.repositories.PersonRepository;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.stereotype.Service;
7
+
8
+@Service
9
+public class PersonService {
10
+
11
+    @Autowired
12
+    PersonRepository personRepository;
13
+
14
+    public Iterable<Person> getPersonList(){
15
+        return personRepository.findAll();
16
+    }
17
+
18
+    public Person getPersonById(Long id){
19
+        return personRepository.findOne(id);
20
+    }
21
+
22
+    public Person savePerson(Person person){
23
+        return personRepository.save(person);
24
+    }
25
+
26
+    public void deletePerson(Long id){
27
+        personRepository.delete(id);
28
+    }
29
+}

+ 0
- 4
src/main/resources/application-h2.properties 查看文件

1
-spring.datasource.url=jdbc:h2:mem:testdb;Mode=Oracle
2
-spring.datasource.platform=h2
3
-spring.jpa.hibernate.ddl-auto=none
4
-spring.datasource.continue-on-error=true

+ 4
- 3
src/main/resources/application.properties 查看文件

1
-spring.profiles.active=h2
2
-
3
-spring.jpa.database-platform=org.hibernate.dialect.Oracle10gDialect
1
+spring.datasource.url=jdbc:mysql://localhost:3306/person?useSSL=false
2
+spring.datasource.username=root
3
+spring.datasource.password=qwerty
4
+spring.jpa.hibernate.ddl-auto=create

+ 94
- 0
src/test/java/io/zipcoder/crudapp/PersonControllerTest.java 查看文件

1
+package io.zipcoder.crudapp;
2
+
3
+import io.zipcoder.crudapp.controllers.PersonController;
4
+import io.zipcoder.crudapp.models.Person;
5
+import io.zipcoder.crudapp.services.PersonService;
6
+import org.junit.Before;
7
+import org.junit.Test;
8
+import org.junit.runner.RunWith;
9
+import org.springframework.beans.factory.annotation.Autowired;
10
+import org.springframework.boot.test.context.SpringBootTest;
11
+import org.springframework.boot.test.mock.mockito.MockBean;
12
+import org.springframework.http.HttpStatus;
13
+import org.springframework.http.ResponseEntity;
14
+import org.springframework.test.context.junit4.SpringRunner;
15
+
16
+import java.util.ArrayList;
17
+import java.util.List;
18
+
19
+import static org.assertj.core.api.Java6Assertions.assertThat;
20
+import static org.mockito.BDDMockito.given;
21
+
22
+@SpringBootTest
23
+@RunWith(SpringRunner.class)
24
+public class PersonControllerTest {
25
+    List<Person> list;
26
+    Person testPerson = new Person("Test", "Person");
27
+
28
+    @Before
29
+    public void setup(){
30
+        list = new ArrayList<>();
31
+        list.add(testPerson);
32
+    }
33
+
34
+    @Autowired
35
+    PersonController personController;
36
+
37
+    @MockBean
38
+    PersonService personService;
39
+
40
+    @Test
41
+    public void testGetPersonList(){
42
+        given(
43
+                this.personService.getPersonList()
44
+        ).willReturn(
45
+                list
46
+        );
47
+        ResponseEntity<Iterable<Person>> actual = personController.getPersonList();
48
+        assertThat(actual)
49
+                .isEqualTo(new ResponseEntity<>(list, HttpStatus.OK));
50
+    }
51
+
52
+    @Test
53
+    public void testGetPersonById(){
54
+        given(this.personService.getPersonById(1L)
55
+        ).willReturn(testPerson);
56
+
57
+        ResponseEntity<?> actual = personController.getPersonById(1L);
58
+        assertThat(actual).isEqualTo(new ResponseEntity<>(testPerson, HttpStatus.OK));
59
+    }
60
+
61
+    @Test
62
+    public void testGetPersonById_null(){
63
+        given(this.personService.getPersonById(2L)
64
+        ).willReturn(null);
65
+
66
+        ResponseEntity<?> actual = personController.getPersonById(2L);
67
+        assertThat(actual).isEqualTo(new ResponseEntity<>(null, HttpStatus.NOT_FOUND));
68
+    }
69
+
70
+    @Test
71
+    public void testCreatePerson(){
72
+        given(this.personService.savePerson(testPerson)
73
+        ).willReturn(testPerson);
74
+
75
+        ResponseEntity<?> actual = personController.createPerson(testPerson);
76
+        assertThat(actual).isEqualTo(new ResponseEntity<>(testPerson,HttpStatus.CREATED));
77
+    }
78
+
79
+    @Test
80
+    public void testUpdatePerson(){
81
+        testPerson.setFirstName("Bill");
82
+        given(this.personService.savePerson(testPerson)
83
+        ).willReturn(testPerson);
84
+
85
+        ResponseEntity<?> actual = personController.updatePerson(1L, testPerson);
86
+        assertThat(actual).isEqualTo(new ResponseEntity<>(testPerson,HttpStatus.OK));
87
+    }
88
+
89
+    @Test
90
+    public void testDelete(){
91
+        ResponseEntity<?> actual = personController.deletePerson(1L);
92
+        assertThat(actual).isEqualTo(new ResponseEntity(HttpStatus.NO_CONTENT));
93
+    }
94
+}

+ 158
- 0
src/test/java/io/zipcoder/crudapp/PersonControllerTestMVC.java 查看文件

1
+package io.zipcoder.crudapp;
2
+
3
+import com.fasterxml.jackson.databind.ObjectMapper;
4
+import io.zipcoder.crudapp.controllers.PersonController;
5
+import io.zipcoder.crudapp.models.Person;
6
+import io.zipcoder.crudapp.services.PersonService;
7
+import org.apache.catalina.filters.CorsFilter;
8
+import org.junit.Before;
9
+import org.junit.Test;
10
+import org.junit.runner.RunWith;
11
+import org.mockito.InjectMocks;
12
+import org.mockito.Mock;
13
+import org.mockito.MockitoAnnotations;
14
+import org.springframework.boot.test.context.SpringBootTest;
15
+import org.springframework.http.MediaType;
16
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
17
+import org.springframework.test.context.web.WebAppConfiguration;
18
+import org.springframework.test.web.servlet.MockMvc;
19
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
20
+
21
+import java.util.ArrayList;
22
+import java.util.List;
23
+
24
+import static org.hamcrest.Matchers.hasSize;
25
+import static org.hamcrest.Matchers.is;
26
+import static org.mockito.Mockito.*;
27
+import static org.mockito.Mockito.verifyNoMoreInteractions;
28
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
29
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
30
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
31
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
32
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
33
+
34
+
35
+// ========== Looked further into the readme. Testing Controller the 'right' way now =========//
36
+
37
+@WebAppConfiguration
38
+@SpringBootTest
39
+@RunWith(SpringJUnit4ClassRunner.class)
40
+public class PersonControllerTestMVC {
41
+    List<Person> list;
42
+    Person testPerson = new Person("Test", "Person");
43
+    private MockMvc mockMvc;
44
+
45
+    @Mock
46
+    private PersonService personService;
47
+
48
+    @InjectMocks
49
+    private PersonController personController;
50
+
51
+    @Before
52
+    public void init(){
53
+        list = new ArrayList<>();
54
+        list.add(testPerson);
55
+
56
+        MockitoAnnotations.initMocks(this);
57
+        mockMvc = MockMvcBuilders
58
+                .standaloneSetup(personController)
59
+                .build();
60
+    }
61
+
62
+    // =================== Get All Users =================== //
63
+
64
+    @Test
65
+    public void testGetPersonList() throws Exception {
66
+        when(personService.getPersonList()).thenReturn(list);
67
+
68
+        mockMvc.perform(get("/people"))
69
+                .andExpect(status().isOk())
70
+                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
71
+                .andExpect(jsonPath("$", hasSize(1)))
72
+                .andExpect(jsonPath("$[0].firstName", is("Test")))
73
+                .andExpect(jsonPath("$[0].lastName",is("Person")));
74
+
75
+        verify(personService,times(1)).getPersonList();
76
+        verifyNoMoreInteractions(personService);
77
+    }
78
+
79
+    // ======================== Get User By ID ======================== //
80
+
81
+    @Test
82
+    public void testGetPersonById() throws Exception {
83
+        when(personService.getPersonById(1L)).thenReturn(testPerson);
84
+
85
+        mockMvc.perform(get("/people/{id}",1))
86
+                .andExpect(status().isOk())
87
+                .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
88
+                .andExpect(jsonPath("$.firstName",is("Test")))
89
+                .andExpect(jsonPath("$.lastName",is("Person")));
90
+
91
+        verify(personService,times(1)).getPersonById(1L);
92
+        verifyNoMoreInteractions(personService);
93
+    }
94
+
95
+    @Test
96
+    public void testGetPersonById_fail_404_notFound() throws Exception {
97
+        when(personService.getPersonById(2L)).thenReturn(null);
98
+
99
+        mockMvc.perform(get("/people/{id}",2))
100
+                .andExpect(status().isNotFound());
101
+
102
+        verify(personService, times(1)).getPersonById(2L);
103
+        verifyNoMoreInteractions(personService);
104
+    }
105
+
106
+    // ======================== Create Person ======================== //
107
+
108
+    @Test
109
+    public void testCreatePerson() throws Exception {
110
+        when(personService.savePerson(testPerson)).thenReturn(testPerson);
111
+
112
+        mockMvc.perform(post("/people")
113
+                    .contentType(MediaType.APPLICATION_JSON)
114
+                    .content(asJsonString(testPerson)))
115
+                .andExpect(status().isCreated());
116
+
117
+        verify(personService,times(1)).savePerson(testPerson);
118
+        verifyNoMoreInteractions(personService);
119
+    }
120
+
121
+    // ======================== Update Person ======================== //
122
+
123
+    @Test
124
+    public void testUpdatePerson() throws Exception {
125
+        when(personService.savePerson(testPerson)).thenReturn(testPerson);
126
+
127
+        mockMvc.perform(put("/people/{id}",1)
128
+                .contentType(MediaType.APPLICATION_JSON)
129
+                .content(asJsonString(testPerson)))
130
+                .andExpect(status().isOk());
131
+
132
+        verify(personService, times(1)).savePerson(testPerson);
133
+        verifyNoMoreInteractions(personService);
134
+    }
135
+
136
+    // ======================== Delete Person ======================== //
137
+
138
+    @Test
139
+    public void testDeletePerson() throws Exception {
140
+        doNothing().when(personService).deletePerson(1L);
141
+
142
+        mockMvc.perform(delete("/people/{id}",1))
143
+                .andExpect(status().isNoContent());
144
+
145
+        verify(personService, times(1)).deletePerson(1L);
146
+        verifyNoMoreInteractions(personService);
147
+    }
148
+
149
+
150
+    public static String asJsonString(final Object obj) {
151
+        try {
152
+            final ObjectMapper mapper = new ObjectMapper();
153
+            return mapper.writeValueAsString(obj);
154
+        } catch (Exception e) {
155
+            throw new RuntimeException(e);
156
+        }
157
+    }
158
+}

+ 75
- 0
src/test/java/io/zipcoder/crudapp/PersonServiceTest.java 查看文件

1
+package io.zipcoder.crudapp;
2
+
3
+import io.zipcoder.crudapp.models.Person;
4
+import io.zipcoder.crudapp.repositories.PersonRepository;
5
+import io.zipcoder.crudapp.services.PersonService;
6
+import org.junit.Before;
7
+import org.junit.Test;
8
+import org.junit.runner.RunWith;
9
+import org.springframework.beans.factory.annotation.Autowired;
10
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
11
+import org.springframework.boot.test.context.SpringBootTest;
12
+import org.springframework.boot.test.mock.mockito.MockBean;
13
+import org.springframework.test.context.junit4.SpringRunner;
14
+
15
+import java.util.ArrayList;
16
+import java.util.List;
17
+
18
+import static org.assertj.core.api.Java6Assertions.assertThat;
19
+import static org.mockito.BDDMockito.given;
20
+import static org.mockito.Mockito.verify;
21
+import static org.mockito.Mockito.when;
22
+
23
+@SpringBootTest
24
+@RunWith(SpringRunner.class)
25
+public class PersonServiceTest {
26
+    List<Person> list;
27
+    Person testPerson = new Person("Test", "Person");
28
+    @Before
29
+    public void setup(){
30
+        list = new ArrayList<>();
31
+        list.add(testPerson);
32
+    }
33
+
34
+    @MockBean
35
+    PersonRepository personRepository;
36
+
37
+    @Autowired
38
+    PersonService personService;
39
+
40
+    @Test
41
+    public void testGetPersonList(){
42
+        given(
43
+            this.personRepository.findAll()
44
+        ).willReturn(
45
+            list
46
+        );
47
+        Iterable<Person> actual = personService.getPersonList();
48
+        assertThat(actual)
49
+            .isEqualTo(list);
50
+    }
51
+
52
+    @Test
53
+    public void testGetPersonById(){
54
+        given(this.personRepository.findOne(1L)
55
+        ).willReturn(testPerson);
56
+
57
+        Person actual = personService.getPersonById(1L);
58
+        assertThat(actual).isEqualTo(testPerson);
59
+    }
60
+
61
+    @Test
62
+    public void testSavePerson(){
63
+        given(this.personRepository.save(testPerson)
64
+        ).willReturn(testPerson);
65
+
66
+        Person actual = personService.savePerson(testPerson);
67
+        assertThat(actual).isEqualTo(testPerson);
68
+    }
69
+
70
+    @Test
71
+    public void testDelete(){
72
+        personService.deletePerson(1L);
73
+        verify(personRepository).delete(1L);
74
+    }
75
+}