2024-08-06
One-liner
雁子南飞时,故人忆往事。 --- 《醉柳引·故人安在兮》 · 月雩
Spring Boot Mock Database
Here's an example of a Spring Boot test with a mock database:
@SpringBootTest
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.NONE)
@AutoConfigureMockMvc
public class ReaderControllerTest {
@MockBean
private ReaderRepository readerRepository;
@Autowired
private MockMvc mockMvc;
@Test
void createReaderTest() throws Exception {
var reader = ReaderData.getReader();
when(readerRepository.findByEmail(anyString())).thenReturn(Optional.empty());
when(readerRepository.save(null)).thenReturn(reader);
var json = """
{ "name": "%s", "email": "%s" }
""".formatted(reader.getName(), reader.getEmail());
mockMvc
.perform(
post("/user").contentType("application/json").content(json))
.andExpect(status().isOk());
}
}
Spock vs JUnit
Spock and JUnit are both Java testing frameworks, but they have some significant differences in design, features, and usage.
Commonalities
- Testing Frameworks: Both are used for writing and running automated tests.
- Integration Tools: Both can be integrated with common build tools like Maven and Gradle.
- Unit Test Support: Both support writing unit tests.
Differences
1. Syntax and Language Features
- Spock: Uses Groovy, making test code more concise and readable. Spock specs (
Specification
) are based on Groovy DSL.class MySpec extends Specification {
def "feature method"() {
expect:
1 + 1 == 2
}
} - JUnit: Uses Java. Test classes and methods are annotated.
public class MyTest {
@Test
public void testAddition() {
assertEquals(2, 1 + 1);
}
}
2. Test Lifecycle
- Spock: Uses
setup
,setupSpec
,cleanup
,cleanupSpec
for defining lifecycle methods.class MySpec extends Specification {
def setup() { /* runs before every test method */ }
def cleanup() { /* runs after every test method */ }
def setupSpec() { /* runs once before the first test method */ }
def cleanupSpec() { /* runs once after the last test method */ }
} - JUnit: Uses
@Before
,@After
,@BeforeClass
,@AfterClass
annotations.public class MyTest {
@Before
public void setUp() { /* runs before every test method */ }
@After
public void tearDown() { /* runs after every test method */ }
@BeforeClass
public static void beforeAll() { /* runs once before the first test method */ }
@AfterClass
public static void afterAll() { /* runs once after the last test method */ }
}