
Unit Test Utility Methods
- 20 installs
- 318 repo stars
- Updated June 22, 2026
- giuseppe-trisciuoglio/developer-kit-claude-code
This is a copy of unit-test-utility-methods by giuseppe-trisciuoglio - installs and ranking accrue to the original listing.
Helps with testing & qa tasks.
About
unit-test-utility-methods is a Claude Code skill for testing & qa. It helps solo builders move faster with AI-assisted development.
- unit-test-utility-methods
- Testing & QA
- AI-coding skill
Unit Test Utility Methods by the numbers
- 20 all-time installs (skills.sh)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit-claude-code --skill unit-test-utility-methodsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 20 |
|---|---|
| repo stars | ★ 318 |
| Last updated | June 22, 2026 |
| Repository | giuseppe-trisciuoglio/developer-kit-claude-code ↗ |
What it does
Helps with testing & qa tasks.
Files
Unit Testing Utility Classes and Static Methods
Overview
This skill generates tests for utility classes with static helper methods and pure functions. It provides patterns for testing null handling, edge cases, boundary conditions, and common utilities like string manipulation, calculations, data validation, and collections. Pure functions require no mocking.
When to Use
Use this skill when:
- Writing tests for utility/helper classes with static methods
- Testing pure functions with no state or side effects
- Testing string manipulation, formatting, or transformation utilities
- Testing calculation, conversion, or math helper functions
- Testing data validation and formatter utilities
- Verifying null/empty input handling in utility code
- Testing collections or array helper methods
Instructions
1. Create test class: Name it after the utility (e.g., StringUtilsTest) 2. Test happy path: Valid inputs with expected outputs 3. Test edge cases: null, empty, whitespace, single elements 4. Test boundary conditions: max/min values, large numbers, precision 5. Use descriptive names: shouldCapitalizeFirstLetter instead of test1 6. Use AssertJ: For readable, chainable assertions 7. Use `@ParameterizedTest`: For multiple similar inputs (see references/parameterized-tests.md) 8. Avoid mocking: Pure utilities need no mocks
Examples
Basic Static Utility Test
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.*;
class StringUtilsTest {
@Test
void shouldCapitalizeFirstLetter() {
assertThat(StringUtils.capitalize("hello")).isEqualTo("Hello");
}
@Test
void shouldReturnNullForNullInput() {
assertThat(StringUtils.capitalize(null)).isNull();
}
@Test
void shouldHandleEmptyString() {
assertThat(StringUtils.capitalize("")).isEmpty();
}
@Test
void shouldHandleSingleCharacter() {
assertThat(StringUtils.capitalize("a")).isEqualTo("A");
}
}Comprehensive Example: isEmpty Implementation
// Input: public static boolean isEmpty(String str)
// { return str == null || str.trim().isEmpty(); }
class StringUtilsTest {
@Test
void shouldReturnTrueForNullString() {
assertThat(StringUtils.isEmpty(null)).isTrue();
}
@Test
void shouldReturnTrueForEmptyString() {
assertThat(StringUtils.isEmpty("")).isTrue();
}
@Test
void shouldReturnTrueForWhitespaceOnly() {
assertThat(StringUtils.isEmpty(" ")).isTrue();
}
@Test
void shouldReturnFalseForNonEmptyString() {
assertThat(StringUtils.isEmpty("hello")).isFalse();
}
}Null-Safe Utility
class NullSafeUtilsTest {
@Test
void shouldReturnDefaultWhenNull() {
assertThat(NullSafeUtils.getOrDefault(null, "default")).isEqualTo("default");
}
@Test
void shouldReturnValueWhenNotNull() {
assertThat(NullSafeUtils.getOrDefault("value", "default")).isEqualTo("value");
}
@Test
void shouldReturnFalseWhenBlank() {
assertThat(NullSafeUtils.isNotBlank(null)).isFalse();
assertThat(NullSafeUtils.isNotBlank(" ")).isFalse();
}
}Math/Calculation Utility
class MathUtilsTest {
@Test
void shouldCalculatePercentage() {
assertThat(MathUtils.percentage(25, 100)).isEqualTo(25.0);
}
@Test
void shouldHandleZeroDivisor() {
assertThat(MathUtils.percentage(50, 0)).isZero();
}
@Test
void shouldRoundToDecimalPlaces() {
assertThat(MathUtils.round(3.14159, 2)).isEqualTo(3.14);
}
@Test
void shouldHandleFloatingPointWithTolerance() {
assertThat(MathUtils.multiply(0.1, 0.2))
.isCloseTo(0.02, within(0.0001));
}
}Collection Utility
class CollectionUtilsTest {
@Test
void shouldFilterList() {
List<Integer> result = CollectionUtils.filter(List.of(1, 2, 3, 4), n -> n % 2 == 0);
assertThat(result).containsExactly(2, 4);
}
@Test
void shouldHandleNullList() {
assertThat(CollectionUtils.filter(null, n -> true)).isEmpty();
}
@Test
void shouldJoinWithSeparator() {
assertThat(CollectionUtils.join(List.of("a", "b", "c"), "-")).isEqualTo("a-b-c");
}
@Test
void shouldDeduplicateList() {
assertThat(CollectionUtils.deduplicate(List.of("a", "b", "a")))
.containsExactlyInAnyOrder("a", "b");
}
}Data Validation Utility
class ValidatorUtilsTest {
@Test
void shouldValidateEmailFormat() {
assertThat(ValidatorUtils.isValidEmail("user@example.com")).isTrue();
assertThat(ValidatorUtils.isValidEmail("invalid")).isFalse();
}
@Test
void shouldValidateUrlFormat() {
assertThat(ValidatorUtils.isValidUrl("https://example.com")).isTrue();
assertThat(ValidatorUtils.isValidUrl("not a url")).isFalse();
}
@Test
void shouldValidateCreditCard() {
assertThat(ValidatorUtils.isValidCreditCard("4532015112830366")).isTrue();
assertThat(ValidatorUtils.isValidCreditCard("1234567890123456")).isFalse();
}
}Utility with Clock Dependency (Rare)
@ExtendWith(MockitoExtension.class)
class DateUtilsTest {
@Mock
private Clock clock;
@Test
void shouldGetDateFromClock() {
when(clock.instant()).thenReturn(Instant.parse("2024-01-15T10:00:00Z"));
assertThat(DateUtils.today(clock)).isEqualTo(LocalDate.of(2024, 1, 15));
}
}Best Practices
- Test pure functions exclusively - no side effects or state dependency
- Cover happy path and edge cases - null, empty, whitespace, extreme values
- Use descriptive test names -
shouldReturnNullWhenInputIsNull - Use `@ParameterizedTest` for multiple similar inputs (see
references/parameterized-tests.md) - Test boundary conditions - min/max values, overflow, precision
- Avoid mocking pure functions - only mock external dependencies like Clock
- Keep tests independent - no order dependency between tests
Constraints and Warnings
- No mocking static methods: Use reflection utilities only when absolutely necessary
- Pure function requirement: Stateful utilities are harder to test; prefer immutability
- Floating point precision: Never use exact equality; use
isCloseTo(delta) - Null handling consistency: Decide whether utility returns null or throws; test accordingly
- Thread safety: Static utilities must be thread-safe; verify concurrent behavior separately
- Immutable inputs: Document whether utilities modify input parameters
- Edge cases reference: See
references/edge-cases.mdfor boundary testing patterns
Edge Cases and Boundary Testing
Numeric Boundary Conditions
class MathUtilsEdgeCasesTest {
@Test
void shouldHandleMaxInteger() {
assertThat(MathUtils.increment(Integer.MAX_VALUE)).isEqualTo(Integer.MAX_VALUE);
}
@Test
void shouldHandleMinInteger() {
assertThat(MathUtils.decrement(Integer.MIN_VALUE)).isEqualTo(Integer.MIN_VALUE);
}
@Test
void shouldHandleLargeNumbers() {
BigDecimal result = MathUtils.add(
new BigDecimal("999999999999.99"),
new BigDecimal("0.01")
);
assertThat(result).isEqualTo(new BigDecimal("1000000000000.00"));
}
@Test
void shouldHandleFloatingPointPrecision() {
assertThat(MathUtils.multiply(0.1, 0.2))
.isCloseTo(0.02, within(0.0001));
}
}String Edge Cases
class StringUtilsEdgeCasesTest {
@Test
void shouldHandleNullInput() {
assertThat(StringUtils.capitalize(null)).isNull();
}
@Test
void shouldHandleEmptyString() {
assertThat(StringUtils.capitalize("")).isEmpty();
}
@Test
void shouldHandleSingleCharacter() {
assertThat(StringUtils.capitalize("a")).isEqualTo("A");
}
@Test
void shouldHandleUnicodeCharacters() {
assertThat(StringUtils.capitalize("über")).isEqualTo("Über");
}
@Test
void shouldHandleOnlyWhitespace() {
assertThat(StringUtils.trim(" ")).isEmpty();
}
}Collection Edge Cases
class CollectionUtilsEdgeCasesTest {
@Test
void shouldReturnEmptyForNullInput() {
assertThat(CollectionUtils.filter(null, n -> true)).isEmpty();
}
@Test
void shouldReturnEmptyForNoMatches() {
List<Integer> numbers = List.of(1, 3, 5);
assertThat(CollectionUtils.filter(numbers, n -> n % 2 == 0)).isEmpty();
}
@Test
void shouldHandleEmptyCollection() {
assertThat(CollectionUtils.join(List.of(), "-")).isEmpty();
}
@Test
void shouldHandleSingleElement() {
assertThat(CollectionUtils.join(List.of("a"), "-")).isEqualTo("a");
}
}Validation Edge Cases
class ValidatorUtilsEdgeCasesTest {
@Test
void shouldRejectEmptyEmail() {
assertThat(ValidatorUtils.isValidEmail("")).isFalse();
}
@Test
void shouldRejectNullEmail() {
assertThat(ValidatorUtils.isValidEmail(null)).isFalse();
}
@Test
void shouldHandleLongStrings() {
String longString = "a".repeat(10000);
assertThat(StringUtils.truncate(longString, 100)).hasSize(100);
}
@Test
void shouldHandleSpecialCharactersInUrls() {
assertThat(ValidatorUtils.isValidUrl("https://example.com/path?query=value"))
.isTrue();
}
}Floating Point Precision Rules
| Operation | Use | Example |
|---|---|---|
| Addition | isCloseTo(delta) | isCloseTo(0.3, within(0.001)) |
| Comparison | isEqualTo() | Use BigDecimal for exact decimals |
| Percentage | Tolerance-based | isCloseTo(expected, within(0.01)) |
Parameterized Tests for Utility Methods
Use @ParameterizedTest for testing multiple similar inputs efficiently.
ValueSource - Single Parameter
@ParameterizedTest
@ValueSource(strings = {"", " ", "null", " \t "})
void shouldConsiderFalsyValuesAsEmpty(String input) {
assertThat(StringUtils.isEmpty(input)).isTrue();
}CsvSource - Multiple Parameters
@ParameterizedTest
@CsvSource({
"hello, HELLO",
"world, WORLD",
"test, TEST",
"123abc, 123ABC"
})
void shouldConvertToUpperCase(String input, String expected) {
assertThat(StringUtils.toUpperCase(input)).isEqualTo(expected);
}CsvSource - Email Validation
@ParameterizedTest
@CsvSource({
"user@example.com, true",
"test@domain.org, true",
"invalid-email, false",
'", false',
"no-at-sign.com, false"
})
void shouldValidateEmailsCorrectly(String email, boolean expected) {
assertThat(ValidatorUtils.isValidEmail(email)).isEqualTo(expected);
}MethodSource - Complex Objects
static Stream<Arguments> stringTransformationCases() {
return Stream.of(
Arguments.of("hello", "hello-world", "hello-world"),
Arguments.of("Hello World", "hello_world", "hello_world"),
Arguments.of("Test@123", "test123", "test123")
);
}
@ParameterizedTest
@MethodSource("stringTransformationCases")
void shouldTransformStringsCorrectly(String input, String separator, String expected) {
assertThat(StringUtils.toSlug(input, separator)).isEqualTo(expected);
}Null and Empty Sources
@ParameterizedTest
@NullSource
@EmptySource
void shouldHandleNullAndEmpty(String input) {
assertThat(StringUtils.isBlank(input)).isTrue();
}
@ParameterizedTest
@NullAndEmptySource
void shouldHandleNullEmptyAndBlank(String input) {
assertThat(StringUtils.isBlank(input)).isTrue();
}