# Migrating from Developing Asynchronous Multi-Threading Programs to Reactive Programs in Java
## 7 Evaluation of Results
### Functional Equivalence
```
Feature:UserTweetManagement Scenario:Registerauser,createatweet,andverifytweetexistence Givenanewuserisregisteredwithvaliddetails Whentheuserpostsavalidtweet Andtheuserretrievestheirtweets Thentheuser'sweetshouldbeincludedintheretrievedtweets Scenario:Attempttocreateatweetwithnocontent Givenanewuserisregisteredwithvaliddetails Whentheuserattemptstopostatweetwithnocontent Thentheresponseshouldindicateacontentvalidationerror Scenario:Attempttocreateatweetwithinsufficientcontentlength Givenanewuserisregisteredwithvaliddetails Whentheuserattemptstopostatweetwithinsufficientcontent Thentheresponseshouldindicateaminimumcontentlengtherror
#otherscenarios
```  
This Cucumber feature tests the message management functionalities, including one scenario that verifies that a new user can be registered, create a valid message, and retrieve it. It also includes scenarios such as trying to create a message with no content or insufficient content length, which should trigger specific content validation errors. By incorporating such negative checks and edge cases, these tests ensure the system can process user requests as expected, but also properly validate inputs and handle unexpected situations effectively. To execute the Cucumber feature files, the steps must be followed to define the actual translation from Gherkin scenarios to executable Java code. These step implementations run independently against the different backends, ensuring appropriate validation regardless of the underlying implementation. Listing 6 presents two examples of step implementations, showcasing the actual mapping between the high-level descriptions and the required interactions to perform the respective actions. Both method implementations are annotated and parameterized to align with the steps defined in the feature file. As per the first scenario listed, the _registerNewUser_ method is connected to the _Given_ step, while the _verifyTweetInclusion_ is tied to the _Then_ step. These annotations and the specified parameters establish the direct link between the Gherkin steps and the executable code, ensuring that each scenario step triggers the appropriate method. By implementing an average of approximately 150 tests per service, including both unit tests and also various features and scenarios, an estimated code coverage baseline of over 90% was registered, demonstrating that the migration from asynchronous to reactive specifications did not compromise the application's functionality. The test suites consistently produced the same expected results across both implementations, confirming functional equivalence and reinforcing the feasibility of an effective and complete transition to the reactive approach. ```
@Given(\"*anewuserisregisteredwithvaliddetails\") publicvoidregisterNewUser() throwsJsonProcessingException{ Stringurl=USER_SERVICE_BASE_URL+\"/auth/register\"; HttpHeadersheaders=newHttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); LinkedMultiValueMap<String,String>body= newLinkedMultiValueMap<>(); body.add(\"userName\",generateRandomUsername()); body.add(\"email\",generateRandomEmail()); //additionoftheotherfields HttpEntity<LinkedMultiValueMap<String,String>>requestEntity= newHttpEntity>(body,headers); ResponseEntity<String>response=restTemplate.postForEntity(url,requestEntity,String.class); assertEquals(HttpStatus.OK,response.getStatusCode()); AuthenticationResponseauthResponse=objectMapper.readValue(response.getBody(),AuthenticationResponse.class); userId=UUID.fromString( getClaimFromToken(authResponse.getToken(),\"user_id\") ); } }
```  
```
@Then(\"theuser'sweetshouldbeincludedintheretrievedtweets\") publicvoidverifyTweetInclusion() throwsException{ TweetDto[]tweetsArray=objectMapper.readValue(response.getBody(),TweetDto[].class); List<TweetDto>tweets=Arrays.asList(tweetsArray); assertTrue( tweets.stream().anyMatch( tweet-> 'Thisisavalidtweet. '.equals(tweet.getContent())&& tweetId.equals(tweet.getId()) ) ); } }
```