1 /*
2  * Copyright 2023 Code Intelligence GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example;
18 
19 import static org.hamcrest.Matchers.containsString;
20 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
21 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
22 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
23 
24 import com.code_intelligence.jazzer.api.FuzzedDataProvider;
25 import com.code_intelligence.jazzer.junit.FuzzTest;
26 import com.example.JunitSpringWebApplication.HelloRequest;
27 import com.fasterxml.jackson.core.JsonProcessingException;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import org.junit.jupiter.api.AfterEach;
30 import org.junit.jupiter.api.Assumptions;
31 import org.junit.jupiter.api.BeforeEach;
32 import org.junit.jupiter.api.Test;
33 import org.springframework.beans.factory.annotation.Autowired;
34 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
35 import org.springframework.http.MediaType;
36 import org.springframework.test.web.servlet.MockMvc;
37 
38 @WebMvcTest
39 public class JunitSpringWebApplicationTests {
40   private static final ObjectMapper mapper = new ObjectMapper();
41 
42   @Autowired private MockMvc mockMvc;
43   private boolean beforeCalled = false;
44 
45   @BeforeEach
beforeEach()46   public void beforeEach() {
47     beforeCalled = true;
48   }
49 
50   @AfterEach
afterEach()51   public void afterEach() {
52     beforeCalled = false;
53   }
54 
55   @Test
unitTestShouldPass()56   public void unitTestShouldPass() throws Exception {
57     mockMvc.perform(get("/hello").param("name", "Maven"));
58   }
59 
60   @Test
unitTestShouldFail()61   public void unitTestShouldFail() throws Exception {
62     mockMvc.perform(get("/buggy-hello").param("name", "error"));
63   }
64 
65   @FuzzTest(maxDuration = "10s")
fuzzTestShouldPass(FuzzedDataProvider data)66   public void fuzzTestShouldPass(FuzzedDataProvider data) throws Exception {
67     if (!beforeCalled) {
68       throw new RuntimeException("BeforeEach was not called");
69     }
70 
71     String name = data.consumeRemainingAsString();
72     mockMvc.perform(get("/hello").param("name", name));
73   }
74 
75   @FuzzTest(maxDuration = "10s")
fuzzTestShouldFail(FuzzedDataProvider data)76   public void fuzzTestShouldFail(FuzzedDataProvider data) throws Exception {
77     if (!beforeCalled) {
78       throw new RuntimeException("BeforeEach was not called");
79     }
80 
81     String name = data.consumeRemainingAsString();
82     mockMvc.perform(get("/buggy-hello").param("name", name))
83         .andExpect(content().string(containsString(name)));
84   }
85 
86   @FuzzTest(maxDuration = "10s")
fuzzTestWithDtoShouldFail(HelloRequest helloRequest)87   public void fuzzTestWithDtoShouldFail(HelloRequest helloRequest) throws Exception {
88     if (!beforeCalled) {
89       throw new RuntimeException("BeforeEach was not called");
90     }
91     Assumptions.assumeTrue(
92         helloRequest != null && helloRequest.name != null && !helloRequest.name.isBlank());
93 
94     mockMvc
95         .perform(post("/hello")
96                      .contentType(MediaType.APPLICATION_JSON)
97                      .content(mapper.writeValueAsString(helloRequest)))
98         .andExpect(content().string(containsString(helloRequest.name)));
99   }
100 }
101