Skip to content

Commit 8b60b83

Browse files
committed
[Examples] Improve Spring Examples
* Use JUnit 5 * Use consistent feature names * Complete the search message scenario * Use a real example of test context pollution
1 parent e800a54 commit 8b60b83

File tree

12 files changed

+114
-99
lines changed

12 files changed

+114
-99
lines changed

examples/spring-txn/pom.xml

+2-7
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
<properties>
1515
<project.Automatic-Module-Name>io.cucumber.examples.spring.txn</project.Automatic-Module-Name>
16-
<spring-boot.version>2.2.5.RELEASE</spring-boot.version>
16+
<spring-boot.version>2.2.6.RELEASE</spring-boot.version>
1717
</properties>
1818

1919
<dependencyManagement>
@@ -71,19 +71,14 @@
7171
</dependency>
7272
<dependency>
7373
<groupId>io.cucumber</groupId>
74-
<artifactId>cucumber-junit</artifactId>
74+
<artifactId>cucumber-junit-platform-engine</artifactId>
7575
<scope>test</scope>
7676
</dependency>
7777
<dependency>
7878
<groupId>org.junit.jupiter</groupId>
7979
<artifactId>junit-jupiter</artifactId>
8080
<scope>test</scope>
8181
</dependency>
82-
<dependency>
83-
<groupId>org.junit.vintage</groupId>
84-
<artifactId>junit-vintage-engine</artifactId>
85-
<scope>test</scope>
86-
</dependency>
8782
<!--
8883
Spring doesn't include the right version for surefire to pickup
8984
TODO: Remove once the surefire or spring is upgraded

examples/spring-txn/src/main/java/io/cucumber/examples/spring/txn/Message.java

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import javax.persistence.ManyToOne;
1111
import javax.persistence.Table;
1212
import java.io.Serializable;
13+
import java.util.StringJoiner;
1314

1415
@Entity
1516
@Table(name = "messages")
@@ -51,4 +52,12 @@ public String getContent() {
5152
public void setContent(String content) {
5253
this.content = content;
5354
}
55+
56+
@Override
57+
public String toString() {
58+
return new StringJoiner(", ", Message.class.getSimpleName() + "[", "]")
59+
.add("id=" + id)
60+
.add("content='" + content + "'")
61+
.toString();
62+
}
5463
}

examples/spring-txn/src/main/java/io/cucumber/examples/spring/txn/MessageRepository.java

+4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33
import org.springframework.data.repository.CrudRepository;
44
import org.springframework.stereotype.Repository;
55

6+
import java.util.List;
7+
68
@Repository
79
public interface MessageRepository extends CrudRepository<Message, Long> {
810

11+
List<Message> findByContentContaining(String content);
12+
913
}

examples/spring-txn/src/main/java/io/cucumber/examples/spring/txn/User.java

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import javax.persistence.Table;
1313
import java.io.Serializable;
1414
import java.util.List;
15+
import java.util.StringJoiner;
1516

1617
@Entity
1718
@Table(name = "users")
@@ -57,4 +58,11 @@ public void setMessages(List<Message> messages) {
5758
this.messages = messages;
5859
}
5960

61+
@Override
62+
public String toString() {
63+
return new StringJoiner(", ", User.class.getSimpleName() + "[", "]")
64+
.add("id=" + id)
65+
.add("username='" + username + "'")
66+
.toString();
67+
}
6068
}

examples/spring-txn/src/test/java/io/cucumber/examples/spring/txn/CucumberTestContextConfiguration.java

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
@SpringBootTest
99
@AutoConfigureMockMvc
1010
public class CucumberTestContextConfiguration {
11+
1112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package io.cucumber.examples.spring.txn;
2+
3+
import io.cucumber.java.en.Given;
4+
import io.cucumber.java.en.Then;
5+
import io.cucumber.java.en.When;
6+
import org.springframework.beans.factory.annotation.Autowired;
7+
8+
import java.util.List;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
import static org.junit.jupiter.api.Assertions.assertAll;
12+
13+
public class MessageStepDefinitions {
14+
15+
@Autowired
16+
private MessageRepository messageRepository;
17+
18+
@Autowired
19+
private UserStepDefinitions userStepDefinitions;
20+
21+
private List<Message> results;
22+
23+
@Given("the user has posted the message {string}")
24+
public void the_user_has_posted_the_message(String content) {
25+
User user = userStepDefinitions.getCurrentUser();
26+
messageRepository.save(new Message(user, content));
27+
}
28+
29+
@Given("a User has posted the following messages:")
30+
public void a_user_has_posted_the_following_messages(List<Message> messages) {
31+
User user = userStepDefinitions.getCurrentUser();
32+
for (Message m : messages) {
33+
m.setAuthor(user);
34+
messageRepository.save(m);
35+
}
36+
}
37+
38+
@When("I search for {string}")
39+
public void i_search_for(String query) {
40+
this.results = messageRepository.findByContentContaining(query);
41+
}
42+
43+
@Then("the results content should be:")
44+
public void the_result_should_be(List<String> contents) {
45+
User user = userStepDefinitions.getCurrentUser();
46+
assertAll("The expected contents created by the user", () -> {
47+
assertThat(results)
48+
.extracting(Message::getContent)
49+
.isEqualTo(contents);
50+
assertThat(results)
51+
.extracting(Message::getAuthor)
52+
.extracting(User::getId)
53+
.allMatch(user.getId()::equals);
54+
});
55+
}
56+
57+
}
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package io.cucumber.examples.spring.txn;
22

3-
import io.cucumber.junit.Cucumber;
4-
import io.cucumber.junit.CucumberOptions;
5-
import org.junit.runner.RunWith;
3+
import io.cucumber.junit.platform.engine.Cucumber;
64

7-
@RunWith(Cucumber.class)
8-
@CucumberOptions
5+
@Cucumber
96
public class RunCucumberTest {
7+
108
}

examples/spring-txn/src/test/java/io/cucumber/examples/spring/txn/SeeMessagesStepDefinitions.java

+7-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package io.cucumber.examples.spring.txn;
22

3-
import io.cucumber.java.en.Given;
43
import io.cucumber.java.en.Then;
54
import io.cucumber.java.en.When;
65
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,38 +12,25 @@
1312
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
1413

1514
public class SeeMessagesStepDefinitions {
16-
@Autowired
17-
private UserRepository userRepository;
18-
19-
@Autowired
20-
private MessageRepository messageRepository;
2115

2216
@Autowired
2317
private MockMvc mockMvc;
2418

25-
private User user;
19+
@Autowired
20+
private UserStepDefinitions userStepDefinitions;
2621

2722
private ResultActions resultActions;
2823

29-
@Given("there is a User")
30-
public void there_is_a_User() {
31-
user = userRepository.save(new User("John Doe"));
32-
}
33-
34-
@Given("the User has posted the message {string}")
35-
public void the_User_has_posted_the_message(String content) {
36-
messageRepository.save(new Message(user, content));
37-
}
38-
3924
@When("I visit the page for the User")
40-
public void I_visit_the_page_for_the_User() throws Exception {
25+
public void i_visit_the_page_for_the_user() throws Exception {
26+
User user = userStepDefinitions.getCurrentUser();
4127
resultActions = mockMvc
42-
.perform(get("/users/" + user.getId()))
43-
.andExpect(status().isOk());
28+
.perform(get("/users/" + user.getId()))
29+
.andExpect(status().isOk());
4430
}
4531

4632
@Then("I should see {string}")
47-
public void I_should_see(String content) throws Exception {
33+
public void i_should_see(String content) throws Exception {
4834
resultActions.andExpect(content().string(containsString(content)));
4935
}
5036

examples/spring-txn/src/test/java/io/cucumber/examples/spring/txn/SpringTransactionHooks.java

+1-35
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import org.springframework.transaction.PlatformTransactionManager;
99
import org.springframework.transaction.TransactionStatus;
1010
import org.springframework.transaction.support.DefaultTransactionDefinition;
11-
import org.springframework.transaction.support.SimpleTransactionStatus;
1211

1312
/**
1413
* <p>
@@ -34,33 +33,12 @@
3433
public class SpringTransactionHooks implements BeanFactoryAware {
3534

3635
private BeanFactory beanFactory;
37-
private String txnManagerBeanName;
3836

3937
@Override
4038
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
4139
this.beanFactory = beanFactory;
4240
}
4341

44-
/**
45-
* @return the (optional) bean name for the transaction manager to be
46-
* obtained - if null, attempt will be made to find a transaction manager
47-
* by bean type
48-
*/
49-
public String getTxnManagerBeanName() {
50-
return txnManagerBeanName;
51-
}
52-
53-
/**
54-
* Setter to allow (optional) bean name to be specified for transaction
55-
* manager bean - if null, attempt will be made to find a transaction manager
56-
* by bean type
57-
*
58-
* @param txnManagerBeanName bean name of transaction manager bean
59-
*/
60-
public void setTxnManagerBeanName(String txnManagerBeanName) {
61-
this.txnManagerBeanName = txnManagerBeanName;
62-
}
63-
6442
private TransactionStatus transactionStatus;
6543

6644
@Before(value = "@txn", order = 100)
@@ -76,18 +54,6 @@ public void rollBackTransaction() {
7654
}
7755

7856
public PlatformTransactionManager obtainPlatformTransactionManager() {
79-
if (txnManagerBeanName == null) {
80-
return beanFactory.getBean(PlatformTransactionManager.class);
81-
} else {
82-
return beanFactory.getBean(txnManagerBeanName, PlatformTransactionManager.class);
83-
}
84-
}
85-
86-
public TransactionStatus getTransactionStatus() {
87-
return transactionStatus;
88-
}
89-
90-
public void setTransactionStatus(SimpleTransactionStatus transactionStatus) {
91-
this.transactionStatus = transactionStatus;
57+
return beanFactory.getBean(PlatformTransactionManager.class);
9258
}
9359
}

examples/spring-txn/src/test/java/io/cucumber/examples/spring/txn/UserStepDefinitions.java

+7-24
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,20 @@
22

33
import io.cucumber.java.en.Given;
44
import org.springframework.beans.factory.annotation.Autowired;
5-
import org.springframework.transaction.support.TransactionSynchronizationManager;
6-
7-
import java.util.List;
8-
9-
import static org.junit.jupiter.api.Assertions.assertTrue;
105

116
public class UserStepDefinitions {
12-
@Autowired
13-
private UserRepository userRepository;
147

158
@Autowired
16-
private MessageRepository messageRepository;
9+
private UserRepository userRepository;
1710

18-
private User user;
11+
private User currentUser;
1912

20-
public void thereIsAuser() {
21-
user = new User();
22-
user.setUsername("testuser");
23-
userRepository.save(user);
13+
@Given("there is a user")
14+
public void there_is_a_user() {
15+
currentUser = userRepository.save(new User("John Doe"));
2416
}
2517

26-
@Given("a User has posted the following messages:")
27-
public void a_User_has_posted_the_following_messages(List<Message> messages) {
28-
thereIsAuser();
29-
for (Message m : messages) {
30-
m.setAuthor(user);
31-
messageRepository.save(m);
32-
}
33-
assertTrue(
34-
TransactionSynchronizationManager.isActualTransactionActive(),
35-
"No transaction is active"
36-
);
18+
public User getCurrentUser() {
19+
return currentUser;
3720
}
3821
}

examples/spring-txn/src/test/resources/io/cucumber/examples/spring/txn/search.feature renamed to examples/spring-txn/src/test/resources/io/cucumber/examples/spring/txn/search-messages.feature

+13-5
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@
44
@txn
55
Feature: Search
66

7+
Background:
8+
Given there is a user
9+
710
Scenario: Find messages by content
811
Given a User has posted the following messages:
912
| content |
1013
| I am making dinner |
1114
| I just woke up |
1215
| I am going to work |
13-
14-
Scenario: Find messages by content using auto-search
15-
Given a User has posted the following messages:
16-
| content |
16+
When I search for "I am"
17+
Then the results content should be:
1718
| I am making dinner |
18-
| I just woke up |
1919
| I am going to work |
20+
21+
Scenario: Find messages by content
22+
Given a User has posted the following messages:
23+
| content |
24+
| I just woke up again |
25+
When I search for "woke up"
26+
Then the results content should be:
27+
| I just woke up again |
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Feature: See Messages
22

33
Scenario: See another user's messages
4-
Given there is a User
5-
And the User has posted the message "this is my message"
4+
Given there is a user
5+
And the user has posted the message "this is my message"
66
When I visit the page for the User
77
Then I should see "this is my message"

0 commit comments

Comments
 (0)