or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-testing.mdindex.mdlaunchers.mdtest-annotations.mdtest-context.mdtest-resources.mdutilities.md

test-annotations.mddocs/

0

# Core Test Annotations

1

2

Essential annotations for mocking, transaction management, and session context control in Quarkus tests. These annotations provide declarative control over test behavior and automatically integrate with the Quarkus testing framework.

3

4

## Capabilities

5

6

### Mock Annotation

7

8

Built-in stereotype for creating mock beans in the CDI container during test execution.

9

10

```java { .api }

11

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})

12

@Retention(RetentionPolicy.RUNTIME)

13

@Stereotype

14

public @interface Mock {}

15

```

16

17

**Usage Example:**

18

```java

19

public interface UserService {

20

User findById(Long id);

21

User save(User user);

22

}

23

24

@Mock

25

@ApplicationScoped

26

public class MockUserService implements UserService {

27

@Override

28

public User findById(Long id) {

29

return new User(id, "Mock User", "mock@example.com");

30

}

31

32

@Override

33

public User save(User user) {

34

user.setId(99L);

35

return user;

36

}

37

}

38

39

public class UserControllerTest {

40

@Inject

41

UserService userService; // Automatically receives MockUserService

42

43

@Test

44

public void testMockService() {

45

User user = userService.findById(1L);

46

assertEquals("Mock User", user.getName());

47

}

48

}

49

```

50

51

### InjectMock Annotation

52

53

Instructs the test engine to inject mock instances, typically used with mocking frameworks like Mockito.

54

55

```java { .api }

56

@Target({ElementType.FIELD, ElementType.PARAMETER})

57

@Retention(RetentionPolicy.RUNTIME)

58

public @interface InjectMock {}

59

```

60

61

**Usage with Mockito:**

62

```java

63

public class OrderServiceTest {

64

@InjectMock

65

PaymentService paymentService;

66

67

@InjectMock

68

InventoryService inventoryService;

69

70

@Inject

71

OrderService orderService; // Real service with mocked dependencies

72

73

@Test

74

public void testOrderProcessing() {

75

// Setup mocks

76

when(inventoryService.isAvailable("ITEM_001")).thenReturn(true);

77

when(paymentService.processPayment(any())).thenReturn(true);

78

79

// Test with mocked dependencies

80

Order order = new Order("ITEM_001", 2);

81

OrderResult result = orderService.processOrder(order);

82

83

assertTrue(result.isSuccess());

84

verify(paymentService).processPayment(any());

85

verify(inventoryService).isAvailable("ITEM_001");

86

}

87

}

88

```

89

90

### TestTransaction Annotation

91

92

Runs the annotated method in a rollback-only JTA transaction, ensuring database changes are automatically reverted.

93

94

```java { .api }

95

@Target({ElementType.METHOD})

96

@Retention(RetentionPolicy.RUNTIME)

97

@InterceptorBinding

98

public @interface TestTransaction {}

99

```

100

101

**Usage Example:**

102

```java

103

public class UserRepositoryTest {

104

@Inject

105

UserRepository userRepository;

106

107

@Test

108

@TestTransaction

109

public void testUserCreation() {

110

// Any database changes are automatically rolled back

111

User user = new User("Alice", "alice@example.com");

112

userRepository.persist(user);

113

114

assertNotNull(user.getId());

115

116

// Verify user exists within transaction

117

User found = userRepository.findById(user.getId());

118

assertEquals("Alice", found.getName());

119

120

// Changes will be rolled back after method completes

121

}

122

123

@Test

124

public void testUserDoesNotExist() {

125

// User from previous test was rolled back

126

List<User> users = userRepository.listAll();

127

assertTrue(users.isEmpty());

128

}

129

}

130

```

131

132

### TestReactiveTransaction Annotation

133

134

Runs the annotated method in a rollback-only reactive transaction for reactive data access.

135

136

```java { .api }

137

@Target({ElementType.METHOD})

138

@Retention(RetentionPolicy.RUNTIME)

139

@InterceptorBinding

140

public @interface TestReactiveTransaction {}

141

```

142

143

**Usage with Reactive Panache:**

144

```java

145

public class ReactiveUserRepositoryTest {

146

@Test

147

@TestReactiveTransaction

148

public Uni<Void> testReactiveUserCreation() {

149

User user = new User("Bob", "bob@example.com");

150

151

return user.persist()

152

.chain(ignored -> {

153

assertNotNull(user.getId());

154

return User.findById(user.getId());

155

})

156

.invoke(found -> {

157

assertEquals("Bob", found.getName());

158

// Transaction will be rolled back

159

})

160

.replaceWithVoid();

161

}

162

}

163

```

164

165

### ActivateSessionContext Annotation

166

167

Activates the HTTP session context before method execution, useful for testing session-scoped beans.

168

169

```java { .api }

170

@Target({ElementType.METHOD})

171

@Retention(RetentionPolicy.RUNTIME)

172

@InterceptorBinding

173

public @interface ActivateSessionContext {}

174

```

175

176

**Usage Example:**

177

```java

178

@SessionScoped

179

public class ShoppingCart implements Serializable {

180

private List<Item> items = new ArrayList<>();

181

182

public void addItem(Item item) {

183

items.add(item);

184

}

185

186

public List<Item> getItems() {

187

return items;

188

}

189

}

190

191

public class ShoppingCartTest {

192

@Inject

193

ShoppingCart cart;

194

195

@Test

196

@ActivateSessionContext

197

public void testSessionScopedCart() {

198

// Session context is automatically activated

199

cart.addItem(new Item("Book", 29.99));

200

cart.addItem(new Item("Pen", 1.99));

201

202

assertEquals(2, cart.getItems().size());

203

assertEquals(31.98, cart.getItems().stream()

204

.mapToDouble(Item::getPrice).sum(), 0.01);

205

}

206

}

207

```

208

209

### TestMethodInvoker Interface

210

211

SPI for altering test method invocation, allowing custom parameter injection and method execution control.

212

213

```java { .api }

214

public interface TestMethodInvoker {

215

boolean handlesMethodParamType(String paramClassName);

216

Object methodParamInstance(String paramClassName);

217

boolean supportsMethod(Class<?> originalTestClass, Method originalTestMethod);

218

Object invoke(Object actualTestInstance, Method actualTestMethod,

219

List<Object> actualTestMethodArgs, String testClassName) throws Throwable;

220

}

221

```

222

223

**Custom Test Method Invoker:**

224

```java

225

public class CustomParameterInvoker implements TestMethodInvoker {

226

@Override

227

public boolean handlesMethodParamType(String paramClassName) {

228

return "com.example.TestContext".equals(paramClassName);

229

}

230

231

@Override

232

public Object methodParamInstance(String paramClassName) {

233

if ("com.example.TestContext".equals(paramClassName)) {

234

return new TestContext("test-environment");

235

}

236

return null;

237

}

238

239

@Override

240

public boolean supportsMethod(Class<?> originalTestClass, Method originalTestMethod) {

241

return Arrays.stream(originalTestMethod.getParameterTypes())

242

.anyMatch(type -> type.getName().equals("com.example.TestContext"));

243

}

244

245

@Override

246

public Object invoke(Object actualTestInstance, Method actualTestMethod,

247

List<Object> actualTestMethodArgs, String testClassName) throws Throwable {

248

// Custom method invocation logic

249

System.out.println("Invoking test with custom context: " + testClassName);

250

return actualTestMethod.invoke(actualTestInstance, actualTestMethodArgs.toArray());

251

}

252

}

253

254

// Usage in test:

255

public class CustomParameterTest {

256

@Test

257

public void testWithCustomParameter(TestContext context) {

258

// TestContext is automatically injected by CustomParameterInvoker

259

assertEquals("test-environment", context.getEnvironment());

260

}

261

}

262

```

263

264

## Advanced Usage Patterns

265

266

### Combining Annotations

267

268

Multiple annotations can be combined for comprehensive test setup:

269

270

```java

271

public class ComprehensiveTest {

272

@InjectMock

273

ExternalService externalService;

274

275

@Test

276

@TestTransaction

277

@ActivateSessionContext

278

public void testWithMultipleContexts(TestContext context) {

279

// Setup mocks

280

when(externalService.getData()).thenReturn("mock-data");

281

282

// Test logic with transaction, session, and custom parameter

283

// All contexts are properly activated and cleaned up

284

}

285

}

286

```

287

288

### Mock Alternatives and Spies

289

290

Using different mocking strategies:

291

292

```java

293

public class AdvancedMockingTest {

294

@InjectMock

295

UserService userService;

296

297

@Test

298

public void testWithSpy() {

299

// Convert mock to spy for partial mocking

300

UserService spy = Mockito.spy(userService);

301

doReturn(true).when(spy).isValidUser(any());

302

// Call real methods for other operations

303

}

304

305

@Test

306

public void testWithAnswer() {

307

when(userService.findById(any())).thenAnswer(invocation -> {

308

Long id = invocation.getArgument(0);

309

return new User(id, "User " + id, id + "@example.com");

310

});

311

312

User user1 = userService.findById(1L);

313

User user2 = userService.findById(2L);

314

315

assertEquals("User 1", user1.getName());

316

assertEquals("User 2", user2.getName());

317

}

318

}

319

```

320

321

### Transaction Isolation Testing

322

323

Testing different transaction scenarios:

324

325

```java

326

public class TransactionTest {

327

@Inject

328

UserRepository userRepository;

329

330

@Test

331

@TestTransaction

332

public void testTransactionalBehavior() {

333

User user = new User("Charlie", "charlie@example.com");

334

userRepository.persist(user);

335

336

// Within transaction, user exists

337

assertTrue(userRepository.isPersistent(user));

338

339

// But will be rolled back after test

340

}

341

342

@Test

343

public void testNonTransactionalBehavior() {

344

// No @TestTransaction - changes persist

345

User user = new User("David", "david@example.com");

346

userRepository.persist(user);

347

348

// Need manual cleanup in @AfterEach

349

}

350

351

@AfterEach

352

public void cleanup() {

353

// Manual cleanup for non-transactional tests

354

userRepository.deleteAll();

355

}

356

}

357

```