or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-stubbing.mdconstructor-mocking.mdindex.mdobject-mocking.mdprivate-methods.mdstatic-mocking.mdstatic-verification.mdverification-extensions.md

advanced-stubbing.mddocs/

0

# Advanced Stubbing

1

2

PowerMock provides enhanced stubbing capabilities that extend beyond standard Mockito when() syntax. These methods are essential for stubbing void methods, private methods, static methods, and scenarios where the standard approach cannot be used due to Java language limitations.

3

4

## Capabilities

5

6

### Custom Answer Stubbing

7

8

Stub methods with custom Answer implementations for complex return logic or side effects.

9

10

```java { .api }

11

static PowerMockitoStubber doAnswer(Answer<?> answer);

12

```

13

14

**Parameters:**

15

- `answer` - Custom Answer implementation defining the method behavior

16

17

**Returns:** PowerMockitoStubber for chaining with method selection

18

19

**Usage Example:**

20

```java

21

@Test

22

@PrepareForTest(DatabaseService.class)

23

public void testCustomAnswer() throws Exception {

24

DatabaseService service = spy(new DatabaseService());

25

26

doAnswer(new Answer<String>() {

27

@Override

28

public String answer(InvocationOnMock invocation) throws Throwable {

29

Object[] args = invocation.getArguments();

30

String query = (String) args[0];

31

return "Result for: " + query.toUpperCase();

32

}

33

}).when(service, "executeQuery", anyString());

34

35

String result = service.performSearch("select * from users");

36

assertEquals("Result for: SELECT * FROM USERS", result);

37

}

38

```

39

40

### Exception Stubbing

41

42

Stub methods to throw specific exceptions, particularly useful for void methods and error scenario testing.

43

44

```java { .api }

45

static PowerMockitoStubber doThrow(Throwable toBeThrown);

46

```

47

48

**Parameters:**

49

- `toBeThrown` - The exception to throw when the stubbed method is called

50

51

**Returns:** PowerMockitoStubber for chaining with method selection

52

53

**Usage Example:**

54

```java

55

@Test

56

@PrepareForTest(FileManager.class)

57

public void testExceptionStubbing() throws Exception {

58

FileManager manager = spy(new FileManager());

59

60

// Stub private method to throw exception

61

doThrow(new IOException("Disk full")).when(manager, "writeToFile", anyString(), anyString());

62

63

// Test that exception is properly handled

64

assertThrows(FileOperationException.class, () -> {

65

manager.saveDocument("document.txt", "content");

66

});

67

}

68

```

69

70

### Real Method Call Stubbing

71

72

Stub methods to call their real implementation, useful for partial mocking scenarios.

73

74

```java { .api }

75

static PowerMockitoStubber doCallRealMethod();

76

```

77

78

**Returns:** PowerMockitoStubber for chaining with method selection

79

80

**Usage Example:**

81

```java

82

@Test

83

@PrepareForTest(MathUtils.class)

84

public void testCallRealMethod() {

85

mockStatic(MathUtils.class);

86

87

// Mock one method but call real implementation for others

88

when(MathUtils.complexCalculation(anyDouble())).thenReturn(100.0);

89

doCallRealMethod().when(MathUtils.class);

90

MathUtils.simpleAddition(5, 3);

91

92

assertEquals(100.0, MathUtils.complexCalculation(50.0), 0.001);

93

assertEquals(8, MathUtils.simpleAddition(5, 3)); // Real implementation

94

}

95

```

96

97

### Do Nothing Stubbing

98

99

Stub void methods to do nothing, overriding default behavior or consecutive call stubbing.

100

101

```java { .api }

102

static PowerMockitoStubber doNothing();

103

```

104

105

**Returns:** PowerMockitoStubber for chaining with method selection

106

107

**Usage Example:**

108

```java

109

@Test

110

@PrepareForTest(Logger.class)

111

public void testDoNothing() throws Exception {

112

Logger logger = spy(new Logger());

113

114

// Stub private void method to do nothing

115

doNothing().when(logger, "writeToFile", anyString());

116

117

// First call does nothing, second call throws exception

118

doNothing().doThrow(new IOException("File locked")).when(logger, "writeToFile", anyString());

119

120

logger.log("First message"); // Does nothing

121

122

assertThrows(IOException.class, () -> {

123

logger.log("Second message"); // Throws exception

124

});

125

}

126

```

127

128

### Return Value Stubbing

129

130

Stub methods to return specific values, particularly useful when when() syntax cannot be used.

131

132

```java { .api }

133

static PowerMockitoStubber doReturn(Object toBeReturned);

134

static PowerMockitoStubber doReturn(Object toBeReturned, Object... othersToBeReturned);

135

```

136

137

**Parameters:**

138

- `toBeReturned` - The value to return when the stubbed method is called

139

- `othersToBeReturned` - Additional values for consecutive calls

140

141

**Returns:** PowerMockitoStubber for chaining with method selection

142

143

**Usage Example:**

144

```java

145

@Test

146

@PrepareForTest(ConfigurationManager.class)

147

public void testDoReturn() throws Exception {

148

ConfigurationManager manager = spy(new ConfigurationManager());

149

150

// Use doReturn when when() would call the real method

151

doReturn("mocked-value").when(manager, "getConfigValue", "key");

152

153

// Multiple return values for consecutive calls

154

doReturn("first", "second", "third").when(manager, "getNextValue");

155

156

assertEquals("mocked-value", manager.getProperty("key"));

157

assertEquals("first", manager.getNext());

158

assertEquals("second", manager.getNext());

159

assertEquals("third", manager.getNext());

160

}

161

```

162

163

## PowerMockitoStubber Interface Methods

164

165

The PowerMockitoStubber interface extends Mockito's Stubber with additional capabilities for static and private methods:

166

167

```java { .api }

168

interface PowerMockitoStubber extends Stubber {

169

void when(Class<?> classMock);

170

<T> PrivatelyExpectedArguments when(T mock, Method method) throws Exception;

171

<T> void when(T mock, Object... arguments) throws Exception;

172

<T> void when(T mock, String methodToExpected, Object... arguments) throws Exception;

173

<T> PrivatelyExpectedArguments when(Class<T> classMock, Method method) throws Exception;

174

<T> void when(Class<T> classMock, Object... arguments) throws Exception;

175

<T> void when(Class<T> classMock, String methodToExpected, Object... parameters) throws Exception;

176

}

177

```

178

179

## Common Patterns

180

181

### Stubbing Static Void Methods

182

183

```java

184

@Test

185

@PrepareForTest(SystemLogger.class)

186

public void testStaticVoidMethodStubbing() {

187

mockStatic(SystemLogger.class);

188

189

// Stub static void method to throw exception

190

doThrow(new RuntimeException("Logging failed")).when(SystemLogger.class);

191

SystemLogger.log(eq("ERROR"), anyString());

192

193

ServiceManager manager = new ServiceManager();

194

195

assertThrows(ServiceException.class, () -> {

196

manager.handleError("Critical error occurred");

197

});

198

}

199

```

200

201

### Consecutive Behavior Stubbing

202

203

```java

204

@Test

205

@PrepareForTest(NetworkService.class)

206

public void testConsecutiveBehavior() throws Exception {

207

NetworkService service = spy(new NetworkService());

208

209

// First call succeeds, second fails, third succeeds again

210

doReturn("success")

211

.doThrow(new NetworkException("Connection timeout"))

212

.doReturn("retry success")

213

.when(service, "attemptConnection", anyString());

214

215

assertEquals("success", service.connect("server1"));

216

assertThrows(NetworkException.class, () -> service.connect("server1"));

217

assertEquals("retry success", service.connect("server1"));

218

}

219

```

220

221

### Stubbing Private Methods with Complex Logic

222

223

```java

224

@Test

225

@PrepareForTest(DataProcessor.class)

226

public void testComplexPrivateMethodStubbing() throws Exception {

227

DataProcessor processor = spy(new DataProcessor());

228

229

doAnswer(invocation -> {

230

String data = (String) invocation.getArguments()[0];

231

if (data.startsWith("PRIORITY")) {

232

return data.toUpperCase();

233

} else {

234

return data.toLowerCase();

235

}

236

}).when(processor, "transformData", anyString());

237

238

String priorityResult = processor.processData("PRIORITY: urgent message");

239

String normalResult = processor.processData("Normal message");

240

241

assertEquals("PRIORITY: URGENT MESSAGE", priorityResult);

242

assertEquals("normal message", normalResult);

243

}

244

```

245

246

### Stubbing with Side Effects

247

248

```java

249

@Test

250

@PrepareForTest(CacheManager.class)

251

public void testSideEffects() throws Exception {

252

CacheManager manager = spy(new CacheManager());

253

AtomicInteger callCount = new AtomicInteger(0);

254

255

doAnswer(invocation -> {

256

callCount.incrementAndGet();

257

String key = (String) invocation.getArguments()[0];

258

return "cached-" + key + "-" + callCount.get();

259

}).when(manager, "getCachedValue", anyString());

260

261

String first = manager.getValue("key1");

262

String second = manager.getValue("key2");

263

264

assertEquals("cached-key1-1", first);

265

assertEquals("cached-key2-2", second);

266

assertEquals(2, callCount.get());

267

}

268

```

269

270

### Mixed Stubbing Approaches

271

272

```java

273

@Test

274

@PrepareForTest(SecurityService.class)

275

public void testMixedStubbing() throws Exception {

276

SecurityService service = spy(new SecurityService());

277

278

// Use when() for return values

279

when(service.validateUser("admin")).thenReturn(true);

280

281

// Use doThrow for exceptions

282

doThrow(new SecurityException("Access denied")).when(service, "checkPermissions", "guest");

283

284

// Use doNothing for void methods

285

doNothing().when(service, "logSecurityEvent", anyString());

286

287

// Use doAnswer for complex logic

288

doAnswer(invocation -> {

289

String action = (String) invocation.getArguments()[0];

290

return "audit-" + action + "-" + System.currentTimeMillis();

291

}).when(service, "generateAuditId", anyString());

292

293

assertTrue(service.validateUser("admin"));

294

assertThrows(SecurityException.class, () -> service.authorize("guest", "read"));

295

String auditId = service.performAction("login");

296

assertTrue(auditId.startsWith("audit-login-"));

297

}

298

```

299

300

## When to Use Advanced Stubbing

301

302

### Use doAnswer() when:

303

- Complex return logic based on input parameters

304

- Side effects need to be performed during method execution

305

- Method behavior depends on object state or external conditions

306

307

### Use doThrow() when:

308

- Stubbing void methods to throw exceptions

309

- Testing error handling and exception propagation

310

- Simulating failure scenarios in dependencies

311

312

### Use doCallRealMethod() when:

313

- Partial mocking where most methods should use real implementation

314

- Testing method interactions while stubbing only specific behaviors

315

- Gradual refactoring where some methods are mocked temporarily

316

317

### Use doNothing() when:

318

- Overriding default behavior of void methods

319

- Consecutive stubbing where some calls should be ignored

320

- Disabling side effects like logging or notifications in tests

321

322

### Use doReturn() when:

323

- Standard when() syntax would call the real method (spies)

324

- Overriding previous exception stubbing

325

- Type safety issues with generic return types

326

327

## Requirements

328

329

- Enhanced stubbing works with both static and instance methods

330

- Classes with stubbed methods must be specified in `@PrepareForTest` annotation

331

- Test must use `@RunWith(PowerMockRunner.class)` or equivalent

332

- Stubbing must be configured before the code under test executes

333

- PowerMockitoStubber chaining must be completed with appropriate when() method call