0
# JUnit Integration
1
2
Comprehensive JUnit 4 and JUnit 5 integration for Log4j testing, providing TestRules, Extensions, and annotations for LoggerContext management, configuration loading, and test lifecycle integration.
3
4
## Capabilities
5
6
### LoggerContextRule (JUnit 4)
7
8
JUnit 4 TestRule for constructing LoggerContext with specified configuration files and managing test lifecycle.
9
10
```java { .api }
11
/**
12
* JUnit 4 TestRule for LoggerContext management
13
* Implements TestRule and LoggerContextAccessor
14
*/
15
public class LoggerContextRule implements TestRule, LoggerContextAccessor {
16
17
/**
18
* Constructor for creating rule with configuration file
19
* @param configLocation Configuration file path relative to classpath
20
*/
21
public LoggerContextRule(String configLocation);
22
23
/**
24
* Retrieves typed appender by name
25
* @param name The appender name
26
* @return The appender instance or null if not found
27
*/
28
public <T extends Appender> T getAppender(String name);
29
30
/**
31
* Retrieves required typed appender, throws if not found
32
* @param name The appender name
33
* @param cls The expected appender class
34
* @return The appender instance
35
* @throws AssertionError if appender not found or wrong type
36
*/
37
public <T extends Appender> T getRequiredAppender(String name, Class<T> cls);
38
39
/**
40
* Convenience method for getting ListAppender
41
* @param name The appender name
42
* @return The ListAppender instance
43
*/
44
public ListAppender getListAppender(String name);
45
46
/**
47
* Gets logger with default name (test class name)
48
* @return Logger instance
49
*/
50
public Logger getLogger();
51
52
/**
53
* Gets logger for specified class
54
* @param cls The class to get logger for
55
* @return Logger instance
56
*/
57
public Logger getLogger(Class<?> cls);
58
59
/**
60
* Gets logger with specified name
61
* @param name The logger name
62
* @return Logger instance
63
*/
64
public Logger getLogger(String name);
65
66
/**
67
* Gets the current configuration
68
* @return Configuration instance
69
*/
70
public Configuration getConfiguration();
71
72
/**
73
* Gets the LoggerContext
74
* @return LoggerContext instance
75
*/
76
public LoggerContext getLoggerContext();
77
78
/**
79
* Triggers reconfiguration of the logging system
80
*/
81
public void reconfigure();
82
83
/**
84
* Creates RuleChain with file cleanup rules
85
* @param files Files to clean up after test
86
* @return RuleChain for combining rules
87
*/
88
public RuleChain withCleanFilesRule(String... files);
89
90
/**
91
* Creates RuleChain with folder cleanup rules
92
* @param folders Folders to clean up after test
93
* @return RuleChain for combining rules
94
*/
95
public RuleChain withCleanFoldersRule(String... folders);
96
}
97
```
98
99
**Usage Examples:**
100
101
```java
102
import org.apache.logging.log4j.core.test.junit.LoggerContextRule;
103
import org.apache.logging.log4j.core.test.appender.ListAppender;
104
import org.junit.Rule;
105
import org.junit.Test;
106
107
public class JUnit4LoggerTest {
108
109
@Rule
110
public LoggerContextRule context = new LoggerContextRule("log4j2-test.xml");
111
112
@Test
113
public void testBasicLogging() {
114
Logger logger = context.getLogger();
115
ListAppender appender = context.getListAppender("TestAppender");
116
117
logger.info("Test message");
118
119
assertEquals(1, appender.getEvents().size());
120
assertEquals("Test message", appender.getMessages().get(0));
121
}
122
123
@Test
124
public void testWithCleanup() {
125
// Use rule chain for automatic cleanup
126
}
127
}
128
129
// With cleanup rules
130
public class FileCleanupTest {
131
132
@Rule
133
public RuleChain rules = new LoggerContextRule("log4j2-file-test.xml")
134
.withCleanFilesRule("test.log", "test.log.1")
135
.withCleanFoldersRule("logs");
136
137
@Test
138
public void testFileLogging() {
139
// Files will be automatically cleaned up after test
140
}
141
}
142
```
143
144
### LoggerContextSource (JUnit 5)
145
146
JUnit 5 annotation for specifying configuration files and lifecycle management.
147
148
```java { .api }
149
/**
150
* JUnit 5 annotation for specifying LoggerContext configuration
151
*/
152
@Target({ElementType.TYPE, ElementType.METHOD})
153
@Retention(RetentionPolicy.RUNTIME)
154
public @interface LoggerContextSource {
155
156
/**
157
* Configuration file name relative to classpath
158
* @return Configuration file path
159
*/
160
String value();
161
162
/**
163
* When to reconfigure the logging system
164
* @return ReconfigurationPolicy enum value
165
*/
166
ReconfigurationPolicy reconfigure() default ReconfigurationPolicy.NEVER;
167
168
/**
169
* Shutdown timeout value
170
* @return Timeout value
171
*/
172
long timeout() default 0;
173
174
/**
175
* Shutdown timeout unit
176
* @return TimeUnit for timeout
177
*/
178
TimeUnit unit() default TimeUnit.SECONDS;
179
}
180
```
181
182
### Named Annotation (JUnit 5)
183
184
Annotation for specifying names of configuration items to inject into JUnit 5 test parameters.
185
186
```java { .api }
187
/**
188
* Specifies name of Appender to inject into JUnit 5 tests
189
*/
190
@Target(ElementType.PARAMETER)
191
@Retention(RetentionPolicy.RUNTIME)
192
public @interface Named {
193
194
/**
195
* Name of configuration item to inject
196
* @return The name string
197
*/
198
String value();
199
}
200
```
201
202
### ReconfigurationPolicy
203
204
Enum indicating when to reconfigure the logging system during tests.
205
206
```java { .api }
207
/**
208
* Indicates when to reconfigure logging system during tests
209
*/
210
public enum ReconfigurationPolicy {
211
/** Never reconfigure during test lifecycle */
212
NEVER,
213
214
/** Reconfigure before each test method */
215
BEFORE_EACH,
216
217
/** Reconfigure after each test method */
218
AFTER_EACH
219
}
220
```
221
222
**JUnit 5 Usage Examples:**
223
224
```java
225
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
226
import org.apache.logging.log4j.core.test.junit.Named;
227
import org.apache.logging.log4j.core.test.appender.ListAppender;
228
import org.junit.jupiter.api.Test;
229
230
@LoggerContextSource("log4j2-test.xml")
231
public class JUnit5LoggerTest {
232
233
@Test
234
public void testWithInjectedAppender(@Named("TestAppender") ListAppender appender,
235
Logger logger) {
236
logger.info("Test message");
237
238
assertEquals(1, appender.getEvents().size());
239
assertEquals("Test message", appender.getMessages().get(0));
240
}
241
242
@Test
243
@LoggerContextSource(value = "log4j2-method-test.xml",
244
reconfigure = ReconfigurationPolicy.BEFORE_EACH)
245
public void testWithMethodConfig(@Named("MethodAppender") ListAppender appender) {
246
// Uses method-specific configuration
247
}
248
}
249
```
250
251
### Additional JUnit Rules
252
253
Supporting TestRules for various testing scenarios.
254
255
```java { .api }
256
/**
257
* TestRule for cleaning up external files after tests
258
*/
259
public class CleanFiles extends AbstractExternalFileCleaner implements TestRule {
260
261
/**
262
* Creates rule for cleaning specified files
263
* @param files Files to clean up
264
* @return CleanFiles rule instance
265
*/
266
public static CleanFiles cleanFiles(String... files);
267
}
268
269
/**
270
* TestRule for cleaning up external folders after tests
271
*/
272
public class CleanFolders extends AbstractExternalFileCleaner implements TestRule {
273
274
/**
275
* Creates rule for cleaning specified folders
276
* @param folders Folders to clean up
277
* @return CleanFolders rule instance
278
*/
279
public static CleanFolders cleanFolders(String... folders);
280
}
281
282
/**
283
* TestRule for JDBC testing setup and teardown
284
*/
285
public class JdbcRule implements TestRule {
286
287
/**
288
* Creates JDBC rule with connection string and setup SQL
289
* @param connectionString JDBC connection string
290
* @param setupSql SQL to execute for setup
291
* @return JdbcRule instance
292
*/
293
public static JdbcRule createRule(String connectionString, String setupSql);
294
}
295
296
/**
297
* TestRule for JNDI testing setup
298
*/
299
public class JndiRule implements TestRule {
300
301
/**
302
* Creates JNDI rule for testing JNDI-based configurations
303
* @return JndiRule instance
304
*/
305
public static JndiRule createRule();
306
}
307
308
/**
309
* TestRule for URL stream handler testing
310
*/
311
public class URLStreamHandlerFactoryRule implements TestRule {
312
313
/**
314
* Creates rule for custom URL stream handlers
315
* @param factory URL stream handler factory
316
* @return URLStreamHandlerFactoryRule instance
317
*/
318
public static URLStreamHandlerFactoryRule create(URLStreamHandlerFactory factory);
319
}
320
```
321
322
### Tags and Categories
323
324
JUnit 5 tags and categories for test organization.
325
326
```java { .api }
327
/**
328
* Container for JUnit 5 tags
329
*/
330
public final class Tags {
331
332
/**
333
* Tag for async logger tests requiring LMAX Disruptor
334
*/
335
public static final String ASYNC_LOGGERS = "async-loggers";
336
}
337
338
/**
339
* Property lookup for testing scenarios
340
*/
341
public class TestPropertyLookup extends AbstractLookup {
342
343
/**
344
* Looks up test-specific properties
345
* @param event The log event
346
* @param key The property key
347
* @return The property value or null
348
*/
349
public String lookup(LogEvent event, String key);
350
}
351
```
352
353
## Usage Patterns
354
355
### JUnit 4 Integration
356
357
```java
358
public class MyLoggerTest {
359
360
@Rule
361
public LoggerContextRule context = new LoggerContextRule("test-config.xml");
362
363
@Test
364
public void testLogging() {
365
Logger logger = context.getLogger();
366
ListAppender appender = context.getListAppender("TestList");
367
368
logger.error("Error message");
369
370
assertEquals(1, appender.getEvents().size());
371
assertEquals(Level.ERROR, appender.getEvents().get(0).getLevel());
372
}
373
}
374
```
375
376
### JUnit 5 Integration
377
378
```java
379
@LoggerContextSource("test-config.xml")
380
class MyLoggerTest {
381
382
@Test
383
void testLogging(@Named("TestList") ListAppender appender, Logger logger) {
384
logger.error("Error message");
385
386
assertEquals(1, appender.getEvents().size());
387
}
388
}
389
```
390
391
### Rule Chaining
392
393
```java
394
@Rule
395
public RuleChain rules = RuleChain
396
.outerRule(new JndiRule())
397
.around(new LoggerContextRule("jndi-config.xml"))
398
.around(CleanFiles.cleanFiles("test.log"));
399
```