agentsclimarketplace

Unit test utility methods

Skill giuseppe-trisciuoglio/developer-kit/plugins/developer-kit-java/skills/unit-test-utility-methods

Modular plugin marketplace for Claude Code and agentic CLIs, with validated, spec-driven skills, agents, commands, and workflows for Java, TypeScript, Python, PHP, AWS, and AI.

Install
npx -y skills add giuseppe-trisciuoglio/developer-kit --skill unit-test-utility-methods

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

What its author says it does

Copied from the file, not written here

Provides patterns for testing utility classes, static methods, and helper functions. Validates pure functions, null handling, edge cases, and boundary conditions. Generates AssertJ assertions and @ParameterizedTest for string utils, math utils, validators, and collection helpers. Use when testing utils, test helpers, helper functions, static methods, or verifying utility code correctness.

SKILL.md

7.1 KB, as published. Nobody here has run it

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("[email protected]")).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.md for boundary testing patterns

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.