or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

additional-answers.mdadditional-matchers.mdadvanced-features.mdannotations.mdargument-matching.mdbdd-testing.mdindex.mdmock-creation.mdstatic-mocking.mdstubbing.mdverification.md

static-mocking.mddocs/

0

# Static and Construction Mocking

1

2

This section covers advanced mocking capabilities introduced in Mockito 3.4+ for mocking static methods and object construction.

3

4

## Static Method Mocking

5

6

### MockedStatic Interface

7

8

Mock static methods within a controlled scope.

9

10

```java { .api }

11

public static <T> MockedStatic<T> mockStatic(Class<T> classToMock)

12

public static <T> MockedStatic<T> mockStatic(Class<T> classToMock, String name)

13

public static <T> MockedStatic<T> mockStatic(Class<T> classToMock, Answer defaultAnswer)

14

public static <T> MockedStatic<T> mockStatic(Class<T> classToMock, MockSettings settings)

15

16

interface MockedStatic<T> extends AutoCloseable {

17

<S> OngoingStubbing<S> when(Verification verification);

18

<S> void verify(Verification verification);

19

void verify(Verification verification, VerificationMode mode);

20

void verifyNoMoreInteractions();

21

void verifyNoInteractions();

22

void clearInvocations();

23

void close();

24

void closeOnDemand();

25

boolean isClosed();

26

}

27

```

28

29

**Usage Examples:**

30

31

```java

32

// Basic static mocking

33

@Test

34

void testStaticMethod() {

35

try (MockedStatic<Math> mockedMath = mockStatic(Math.class)) {

36

// Stub static method

37

mockedMath.when(() -> Math.max(1, 2)).thenReturn(5);

38

39

// Use static method

40

int result = Math.max(1, 2);

41

assertEquals(5, result);

42

43

// Verify static method call

44

mockedMath.verify(() -> Math.max(1, 2));

45

}

46

// Static mock automatically closed

47

}

48

49

// Static mocking with argument matchers

50

@Test

51

void testStaticWithMatchers() {

52

try (MockedStatic<Files> mockedFiles = mockStatic(Files.class)) {

53

mockedFiles.when(() -> Files.exists(any(Path.class)))

54

.thenReturn(true);

55

56

boolean exists = Files.exists(Paths.get("/any/path"));

57

assertTrue(exists);

58

59

mockedFiles.verify(() -> Files.exists(any(Path.class)));

60

}

61

}

62

```

63

64

### Partial Static Mocking

65

66

Mock only specific static methods while keeping others unchanged.

67

68

```java

69

@Test

70

void testPartialStaticMocking() {

71

try (MockedStatic<StringUtils> mockedUtils = mockStatic(StringUtils.class, CALLS_REAL_METHODS)) {

72

// Only mock specific method

73

mockedUtils.when(() -> StringUtils.isEmpty("test")).thenReturn(true);

74

75

// This calls the real method

76

String result = StringUtils.capitalize("hello");

77

assertEquals("Hello", result);

78

79

// This calls the mocked method

80

boolean isEmpty = StringUtils.isEmpty("test");

81

assertTrue(isEmpty);

82

}

83

}

84

```

85

86

## Construction Mocking

87

88

### MockedConstruction Interface

89

90

Mock object construction and initialization.

91

92

```java { .api }

93

public static <T> MockedConstruction<T> mockConstruction(Class<T> classToMock)

94

public static <T> MockedConstruction<T> mockConstruction(Class<T> classToMock, Function<Context, MockSettings> settingsFactory)

95

public static <T> MockedConstruction<T> mockConstruction(Class<T> classToMock, MockInitializer<T> mockInitializer)

96

public static <T> MockedConstruction<T> mockConstruction(Class<T> classToMock, Function<Context, MockSettings> settingsFactory, MockInitializer<T> mockInitializer)

97

98

interface MockedConstruction<T> extends AutoCloseable {

99

List<T> constructed();

100

void close();

101

boolean isClosed();

102

103

interface Context {

104

int getCount();

105

Class<?> getConstructedType();

106

List<Class<?>> getParameterTypes();

107

List<Object> getArguments();

108

}

109

110

interface MockInitializer<T> {

111

void prepare(T mock, Context context) throws Throwable;

112

}

113

}

114

```

115

116

**Usage Examples:**

117

118

```java

119

// Basic construction mocking

120

@Test

121

void testConstructionMocking() {

122

try (MockedConstruction<EmailService> mockedConstruction =

123

mockConstruction(EmailService.class)) {

124

125

// Create objects - they will be mocked

126

EmailService service1 = new EmailService("config1");

127

EmailService service2 = new EmailService("config2");

128

129

// Get constructed mocks

130

List<EmailService> constructed = mockedConstruction.constructed();

131

assertEquals(2, constructed.size());

132

133

// Configure behavior

134

when(service1.sendEmail(any())).thenReturn(true);

135

when(service2.sendEmail(any())).thenReturn(false);

136

137

// Test behavior

138

assertTrue(service1.sendEmail("test"));

139

assertFalse(service2.sendEmail("test"));

140

}

141

}

142

143

// Construction mocking with initialization

144

@Test

145

void testConstructionWithInitializer() {

146

try (MockedConstruction<DatabaseConnection> mockedConstruction =

147

mockConstruction(DatabaseConnection.class, (mock, context) -> {

148

// Initialize each constructed mock

149

when(mock.isConnected()).thenReturn(true);

150

when(mock.getUrl()).thenReturn("mocked-url");

151

})) {

152

153

DatabaseConnection conn1 = new DatabaseConnection("real-url");

154

DatabaseConnection conn2 = new DatabaseConnection("another-url");

155

156

// Both connections have the same mocked behavior

157

assertTrue(conn1.isConnected());

158

assertTrue(conn2.isConnected());

159

assertEquals("mocked-url", conn1.getUrl());

160

assertEquals("mocked-url", conn2.getUrl());

161

}

162

}

163

```

164

165

### Advanced Construction Scenarios

166

167

Context-aware construction mocking with different behaviors.

168

169

```java

170

@Test

171

void testContextAwareConstruction() {

172

try (MockedConstruction<Logger> mockedConstruction =

173

mockConstruction(Logger.class,

174

context -> withSettings().name("logger-" + context.getCount()),

175

(mock, context) -> {

176

String loggerName = "Logger#" + context.getCount();

177

when(mock.getName()).thenReturn(loggerName);

178

179

// Different behavior based on constructor arguments

180

if (context.getArguments().contains("DEBUG")) {

181

when(mock.isDebugEnabled()).thenReturn(true);

182

} else {

183

when(mock.isDebugEnabled()).thenReturn(false);

184

}

185

})) {

186

187

Logger logger1 = new Logger("INFO");

188

Logger logger2 = new Logger("DEBUG");

189

190

assertEquals("Logger#1", logger1.getName());

191

assertEquals("Logger#2", logger2.getName());

192

assertFalse(logger1.isDebugEnabled());

193

assertTrue(logger2.isDebugEnabled());

194

}

195

}

196

```

197

198

## Combining Static and Construction Mocking

199

200

### Complex Mocking Scenarios

201

202

Combine different mocking approaches for comprehensive testing.

203

204

```java

205

@Test

206

void testCombinedMocking() {

207

try (MockedStatic<FileUtils> mockedFileUtils = mockStatic(FileUtils.class);

208

MockedConstruction<FileReader> mockedConstruction =

209

mockConstruction(FileReader.class, (mock, context) -> {

210

when(mock.read()).thenReturn("mocked content");

211

})) {

212

213

// Mock static utility

214

mockedFileUtils.when(() -> FileUtils.exists("test.txt"))

215

.thenReturn(true);

216

217

// Code under test

218

FileProcessor processor = new FileProcessor();

219

String result = processor.processFile("test.txt");

220

221

// Verify both static and construction calls

222

mockedFileUtils.verify(() -> FileUtils.exists("test.txt"));

223

assertEquals(1, mockedConstruction.constructed().size());

224

225

FileReader constructedReader = mockedConstruction.constructed().get(0);

226

verify(constructedReader).read();

227

}

228

}

229

```

230

231

## Best Practices and Limitations

232

233

### Resource Management

234

235

Always use try-with-resources for automatic cleanup.

236

237

```java

238

// CORRECT - automatic cleanup

239

@Test

240

void testWithTryWithResources() {

241

try (MockedStatic<System> mockedSystem = mockStatic(System.class)) {

242

mockedSystem.when(() -> System.currentTimeMillis()).thenReturn(123456L);

243

// Test code

244

} // Automatically closed

245

}

246

247

// INCORRECT - manual cleanup required

248

@Test

249

void testWithManualCleanup() {

250

MockedStatic<System> mockedSystem = mockStatic(System.class);

251

try {

252

mockedSystem.when(() -> System.currentTimeMillis()).thenReturn(123456L);

253

// Test code

254

} finally {

255

mockedSystem.close(); // Must remember to close

256

}

257

}

258

```

259

260

### Thread Safety Considerations

261

262

Static mocks are not thread-safe and should be used carefully in parallel tests.

263

264

```java

265

// Isolate static mocking in test methods

266

class ThreadSafeStaticTest {

267

@Test

268

void test1() {

269

try (MockedStatic<Math> mock = mockStatic(Math.class)) {

270

// Isolated static mock

271

}

272

}

273

274

@Test

275

void test2() {

276

try (MockedStatic<Math> mock = mockStatic(Math.class)) {

277

// Separate static mock instance

278

}

279

}

280

}

281

```

282

283

### Performance Considerations

284

285

Static and construction mocking have performance overhead.

286

287

```java

288

// Use sparingly and scope appropriately

289

@Test

290

void testPerformanceAware() {

291

// Scope static mock to minimum necessary

292

String result;

293

try (MockedStatic<ExpensiveUtil> mock = mockStatic(ExpensiveUtil.class)) {

294

mock.when(() -> ExpensiveUtil.compute(any())).thenReturn("cached");

295

result = ExpensiveUtil.compute("input");

296

}

297

298

// Continue test without static mock overhead

299

assertEquals("cached", result);

300

}

301

```

302

303

### Limitations and Alternatives

304

305

Understanding when static/construction mocking isn't the best solution.

306

307

```java

308

// Instead of mocking static utilities

309

class AvoidStaticMocking {

310

// AVOID if possible

311

@Test

312

void testWithStaticMocking() {

313

try (MockedStatic<UUID> mock = mockStatic(UUID.class)) {

314

mock.when(UUID::randomUUID).thenReturn(fixedUuid);

315

// Test

316

}

317

}

318

319

// PREFER dependency injection

320

@Test

321

void testWithDependencyInjection() {

322

UuidGenerator mockGenerator = mock(UuidGenerator.class);

323

when(mockGenerator.generate()).thenReturn(fixedUuid);

324

325

MyService service = new MyService(mockGenerator);

326

// Test

327

}

328

}

329

```