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

constructor-mocking.mddocs/

0

# Constructor Mocking

1

2

PowerMock enables mocking constructor calls to control object creation, allowing you to test code that creates objects internally without dependency injection. This is essential for testing legacy code that creates dependencies directly rather than accepting them as parameters.

3

4

## Capabilities

5

6

### Constructor Expectation Setup by Class

7

8

Set up expectations for constructor calls on a specific class, allowing you to control what happens when new instances are created.

9

10

```java { .api }

11

static <T> ConstructorExpectationSetup<T> whenNew(Class<T> type);

12

```

13

14

**Parameters:**

15

- `type` - The class whose constructor calls should be intercepted

16

17

**Returns:** ConstructorExpectationSetup for specifying constructor arguments and return behavior

18

19

**Usage Example:**

20

```java

21

@Test

22

@PrepareForTest(FileService.class)

23

public void testConstructorMocking() throws Exception {

24

File mockFile = mock(File.class);

25

26

// Mock constructor to return mock instead of real File

27

whenNew(File.class).withArguments("test.txt").thenReturn(mockFile);

28

when(mockFile.exists()).thenReturn(true);

29

when(mockFile.length()).thenReturn(1024L);

30

31

FileService service = new FileService();

32

long size = service.getFileSize("test.txt"); // Creates new File("test.txt") internally

33

34

assertEquals(1024L, size);

35

verifyNew(File.class).withArguments("test.txt");

36

}

37

```

38

39

### Constructor Expectation by Constructor Reference

40

41

Set up expectations using a specific Constructor reflection object for type-safe constructor mocking.

42

43

```java { .api }

44

static <T> WithOrWithoutExpectedArguments<T> whenNew(Constructor<T> ctor);

45

```

46

47

**Parameters:**

48

- `ctor` - The specific Constructor object to intercept

49

50

**Returns:** Fluent interface for specifying arguments and return behavior

51

52

**Usage Example:**

53

```java

54

@Test

55

@PrepareForTest(DatabaseConnection.class)

56

public void testSpecificConstructor() throws Exception {

57

Constructor<DatabaseConnection> constructor =

58

DatabaseConnection.class.getConstructor(String.class, int.class);

59

DatabaseConnection mockConnection = mock(DatabaseConnection.class);

60

61

whenNew(constructor).withArguments("localhost", 5432).thenReturn(mockConnection);

62

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

63

64

DatabaseService service = new DatabaseService();

65

boolean connected = service.connectToDatabase("localhost", 5432);

66

67

assertTrue(connected);

68

}

69

```

70

71

### Constructor Expectation for Inner Classes

72

73

Set up expectations for constructor calls on inner, local, or anonymous classes using their fully qualified names.

74

75

```java { .api }

76

static <T> ConstructorExpectationSetup<T> whenNew(String fullyQualifiedName) throws Exception;

77

```

78

79

**Parameters:**

80

- `fullyQualifiedName` - The fully qualified name of the inner/local/anonymous class

81

82

**Returns:** ConstructorExpectationSetup for the specified class

83

84

**Usage Example:**

85

```java

86

@Test

87

@PrepareForTest(OuterClass.class)

88

public void testInnerClassConstructor() throws Exception {

89

OuterClass.InnerClass mockInner = mock(OuterClass.InnerClass.class);

90

91

whenNew("com.example.OuterClass$InnerClass")

92

.withArguments("parameter")

93

.thenReturn(mockInner);

94

95

when(mockInner.getValue()).thenReturn("mocked inner value");

96

97

OuterClass outer = new OuterClass();

98

String result = outer.createInnerAndGetValue("parameter");

99

100

assertEquals("mocked inner value", result);

101

}

102

```

103

104

### Constructor Verification

105

106

Verify that constructors were called with expected arguments and frequencies.

107

108

```java { .api }

109

static <T> ConstructorArgumentsVerification verifyNew(Class<T> mock);

110

static <T> ConstructorArgumentsVerification verifyNew(Class<?> mock, VerificationMode mode);

111

```

112

113

**Parameters:**

114

- `mock` - The class whose constructor calls should be verified

115

- `mode` - Verification mode (times, atLeast, never, etc.)

116

117

**Returns:** ConstructorArgumentsVerification for specifying expected arguments

118

119

**Usage Example:**

120

```java

121

@Test

122

@PrepareForTest({HttpClient.class, HttpGet.class})

123

public void testConstructorVerification() throws Exception {

124

HttpClient mockClient = mock(HttpClient.class);

125

HttpGet mockGet = mock(HttpGet.class);

126

127

whenNew(HttpClient.class).withNoArguments().thenReturn(mockClient);

128

whenNew(HttpGet.class).withArguments("http://example.com").thenReturn(mockGet);

129

130

WebService service = new WebService();

131

service.makeGetRequest("http://example.com");

132

133

// Verify constructors were called

134

verifyNew(HttpClient.class).withNoArguments();

135

verifyNew(HttpGet.class).withArguments("http://example.com");

136

verifyNew(HttpGet.class, times(1)).withArguments("http://example.com");

137

}

138

```

139

140

## Constructor Expectation Interface Methods

141

142

```java { .api }

143

interface ConstructorExpectationSetup<T> extends WithOrWithoutExpectedArguments<T>, WithExpectedParameterTypes<T>, WithAnyArguments<T> {

144

}

145

146

interface WithOrWithoutExpectedArguments<T> extends WithExpectedArguments<T>, WithoutExpectedArguments<T> {

147

}

148

149

interface WithExpectedArguments<T> {

150

OngoingStubbing<T> withArguments(Object firstArgument, Object... additionalArguments) throws Exception;

151

}

152

153

interface WithoutExpectedArguments<T> {

154

OngoingStubbing<T> withNoArguments() throws Exception;

155

}

156

157

interface WithExpectedParameterTypes<T> {

158

WithExpectedArguments<T> withParameterTypes(Class<?> parameterType, Class<?>... additionalParameterTypes);

159

}

160

161

interface WithAnyArguments<T> {

162

OngoingStubbing<T> withAnyArguments() throws Exception;

163

}

164

165

interface ConstructorArgumentsVerification {

166

void withArguments(Object argument, Object... additionalArguments) throws Exception;

167

void withNoArguments() throws Exception;

168

}

169

```

170

171

## Common Patterns

172

173

### Testing Code with Hard-coded Dependencies

174

175

```java

176

@Test

177

@PrepareForTest(EmailSender.class)

178

public void testHardcodedDependencies() throws Exception {

179

SMTPClient mockSMTP = mock(SMTPClient.class);

180

181

// Mock constructor that creates SMTP connection internally

182

whenNew(SMTPClient.class)

183

.withArguments("smtp.gmail.com", 587)

184

.thenReturn(mockSMTP);

185

186

when(mockSMTP.sendMessage(anyString(), anyString(), anyString())).thenReturn(true);

187

188

EmailSender sender = new EmailSender();

189

boolean sent = sender.sendEmail("to@example.com", "subject", "body");

190

191

assertTrue(sent);

192

verify(mockSMTP).sendMessage("to@example.com", "subject", "body");

193

verifyNew(SMTPClient.class).withArguments("smtp.gmail.com", 587);

194

}

195

```

196

197

### Testing Exception Handling During Construction

198

199

```java

200

@Test

201

@PrepareForTest(FileProcessor.class)

202

public void testConstructorException() throws Exception {

203

// Mock constructor to throw exception

204

whenNew(BufferedReader.class)

205

.withArguments(any(FileReader.class))

206

.thenThrow(new IOException("File not found"));

207

208

FileProcessor processor = new FileProcessor();

209

210

// Test that the code handles constructor exception properly

211

assertThrows(ProcessingException.class, () -> {

212

processor.processFile("nonexistent.txt");

213

});

214

215

verifyNew(BufferedReader.class).withArguments(any(FileReader.class));

216

}

217

```

218

219

### Testing Object Factory Patterns

220

221

```java

222

@Test

223

@PrepareForTest(ConnectionFactory.class)

224

public void testFactoryPattern() throws Exception {

225

Connection mockConnection = mock(Connection.class);

226

227

// Mock the internal object creation in factory

228

whenNew(PostgreSQLConnection.class)

229

.withArguments(anyString(), anyInt(), anyString(), anyString())

230

.thenReturn(mockConnection);

231

232

when(mockConnection.isValid(anyInt())).thenReturn(true);

233

234

ConnectionFactory factory = new ConnectionFactory();

235

Connection connection = factory.createConnection("postgresql://localhost:5432/testdb");

236

237

assertTrue(connection.isValid(5));

238

verifyNew(PostgreSQLConnection.class)

239

.withArguments("localhost", 5432, "testdb", anyString());

240

}

241

```

242

243

### Constructor Mocking with Parameter Type Matching

244

245

```java

246

@Test

247

@PrepareForTest(DocumentProcessor.class)

248

public void testParameterTypeMatching() throws Exception {

249

Document mockDocument = mock(Document.class);

250

251

// Use parameter type matching when argument values are complex

252

whenNew(Document.class)

253

.withParameterTypes(InputStream.class, String.class)

254

.withArguments(any(InputStream.class), eq("UTF-8"))

255

.thenReturn(mockDocument);

256

257

when(mockDocument.getContent()).thenReturn("mocked content");

258

259

DocumentProcessor processor = new DocumentProcessor();

260

String content = processor.parseDocument(inputStream, "UTF-8");

261

262

assertEquals("mocked content", content);

263

}

264

```

265

266

### Mocking Constructor with Any Arguments

267

268

```java

269

@Test

270

@PrepareForTest(LoggerFactory.class)

271

public void testAnyArguments() throws Exception {

272

Logger mockLogger = mock(Logger.class);

273

274

// Accept any arguments to constructor

275

whenNew(FileLogger.class).withAnyArguments().thenReturn(mockLogger);

276

277

LoggerFactory factory = new LoggerFactory();

278

Logger logger = factory.createLogger("any-name", "any-path", LogLevel.INFO);

279

280

assertEquals(mockLogger, logger);

281

verifyNew(FileLogger.class).withArguments("any-name", "any-path", LogLevel.INFO);

282

}

283

```

284

285

## Requirements

286

287

- Classes whose constructors are mocked must be specified in `@PrepareForTest` annotation

288

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

289

- Constructor expectations must be set up before the code under test executes

290

- Constructor mocking only intercepts calls to `new` - reflection-based construction is not intercepted

291

- Inner class constructor mocking requires the outer class in `@PrepareForTest`