In this lesson, we focus on implementing the Update functionality for our CashCard application using the Test-Driven Development (TDD) approach. We begin by writing a test that defines the expected behavior of our application when updating a CashCard.
Writing the Update Test:
Objective: Update an existing CashCard (ID: 99) to have a new amount of 19.99.
Expected Response: The test expects a 204 NO_CONTENT status code, indicating that the action was successfully performed and no additional content is returned.
Test Implementation:
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
// ... other imports
@Test
@DirtiesContext
void shouldUpdateAnExistingCashCard() {
CashCard cashCardUpdate = new CashCard(null, 19.99, null);
HttpEntity<CashCard> request = new HttpEntity<>(cashCardUpdate);
ResponseEntity<Void> response = restTemplate
.withBasicAuth("sarah1", "abc123")
.exchange("/cashcards/99", HttpMethod.PUT, request, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT);
}
Understanding RestTemplate.exchange()
:
Why Not putForEntity()
? Unlike getForEntity()
and postForEntity()
, there is no putForEntity()
method in RestTemplate
. This is a known issue and is discussed in this GitHub issue.
Using exchange()
: The exchange()
method is a more general-purpose method that allows specifying the HTTP method, request entity, and response type.
ResponseEntity<Void> response = restTemplate
.withBasicAuth("sarah1", "abc123")
.exchange("/cashcards/99", HttpMethod.PUT, request, Void.class);
Creating the HttpEntity
: We wrap the cashCardUpdate
object in an HttpEntity
to include it in the request body.
HttpEntity<CashCard> request = new HttpEntity<>(cashCardUpdate);
Running the Test and Expected Failure:
Test Failure Reason: The test fails because we haven't implemented a handler for the PUT request in our controller.
Observed Failure:
expected: 204 NO_CONTENT
but was: 403 FORBIDDEN
Explanation: Without a controller endpoint to handle the PUT request, Spring Security returns a 403 FORBIDDEN response, indicating that the action is not allowed.
Next Steps:
Learning Points:
From the previous lessons and this exercise, we can extract several key takeaways: