PluginBench
Skill
Fail
Audit score 45

unit-test-utility-methods

giuseppe-trisciuoglio/developer-kit

Test patterns for utility classes, static methods, and pure functions with edge case coverage.

What is unit-test-utility-methods?

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

  • Generates test classes for utility methods with descriptive test names
  • Validates null, empty, whitespace, and boundary condition handling
  • Creates AssertJ assertions for readable, chainable test statements
  • Supports @ParameterizedTest for testing multiple similar inputs
  • Tests pure functions without mocking or state dependencies
  • Covers string manipulation, math calculations, validation, and collection utilities

How to install unit-test-utility-methods

npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill unit-test-utility-methods
Claude Code
Cursor
Windsurf
Cline

How to use unit-test-utility-methods

  1. 1.Create a test class named after the utility (e.g., StringUtilsTest)
  2. 2.Write tests for the happy path with valid inputs and expected outputs
  3. 3.Add tests for edge cases: null, empty strings, whitespace, single elements
  4. 4.Test boundary conditions: max/min values, large numbers, floating-point precision
  5. 5.Use AssertJ assertions for readable comparisons (assertThat().isEqualTo())
  6. 6.Use @ParameterizedTest for multiple similar test cases
  7. 7.Avoid mocking pure functions; only mock external dependencies like Clock if needed
  8. 8.Use descriptive test names like shouldReturnNullWhenInputIsNull

Use cases

Good for
  • Testing string utility methods like capitalize, isEmpty, or trim functions
  • Verifying math helper functions handle zero divisors and floating-point precision
  • Testing data validators for email, URL, or credit card formats
  • Validating collection utilities like filter, join, or deduplicate operations
  • Ensuring null-safe utilities return defaults or handle null inputs correctly
Who it's for
  • Java developers writing unit tests for utility classes
  • Backend engineers testing static helper methods and pure functions
  • QA engineers verifying edge case coverage in utility code
  • Teams standardizing test patterns for reusable utility libraries

unit-test-utility-methods FAQ

When should I use this skill?

Use it when testing utility classes with static methods, pure functions with no state or side effects, or helper functions for string manipulation, calculations, validation, or collections.

Do I need to mock utility methods?

No. Pure utilities require no mocking. Only mock external dependencies like Clock if the utility depends on them. Avoid mocking static methods.

What assertion library does this use?

AssertJ, which provides readable, chainable assertions like assertThat(result).isEqualTo(expected) and isCloseTo() for floating-point comparisons.

How do I test multiple similar inputs?

Use @ParameterizedTest with @ValueSource or @CsvSource to run the same test logic against different input values, reducing code duplication.

What edge cases should I always test?

Always test null inputs, empty strings, whitespace-only strings, single elements, and boundary conditions like zero divisors, max/min values, and floating-point precision.

Full instructions (SKILL.md)

Source of truth, from giuseppe-trisciuoglio/developer-kit.


name: unit-test-utility-methods description: 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. allowed-tools: Read, Write, Bash, Glob, Grep

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.md for boundary testing patterns

Related skills

More from giuseppe-trisciuoglio/developer-kit and the wider catalog.

UNunit-test-wiremock-rest-api logo

unit-test-wiremock-rest-api

giuseppe-trisciuoglio/developer-kit

Unit test REST API integrations with WireMock stubs, request verification, and error simulation.

1.4k installs
WIwiremock-standalone-docker logo

wiremock-standalone-docker

giuseppe-trisciuoglio/developer-kit

Provides patterns and configurations for running WireMock as a standalone Docker container. Generates mock HTTP endpoints, creates stub mappings for testing, validates integration scenarios, and simulates error conditions. Use when you need to mock APIs, create a mock server, stub external services, simulate third-party APIs, or fake API responses for integration testing.

1.0k installsAudited
ZOzod-validation-utilities logo

zod-validation-utilities

giuseppe-trisciuoglio/developer-kit

Creates reusable Zod v4 schemas, validates API payloads, forms, and configuration input, transforms and coerces data safely, and handles validation errors with strong type inference for TypeScript applications. Use when designing validation layers, parsing `z.string()`, `z.object()`, or `z.email()` schemas, or implementing runtime type-safe data validation.

1.2k installsAudited
ADadr-drafting logo

adr-drafting

giuseppe-trisciuoglio/developer-kit

Creates new Architecture Decision Record (ADR) documents for significant architectural changes using a consistent template and repository-aware naming and storage guidance. Use when a user or agent decides on an architectural change, needs to document technical rationale, or wants to add a new ADR to the project history.

1.0k installsAudited
GLgluestack-ui-v4:components logo

gluestack-ui-v4:components

gluestack/agent-skills

Component usage patterns for gluestack-ui v4 - covers component selection, props vs className, compound patterns, icons, and provider setup.

694 installs
GMgmgn-cooking logo

gmgn-cooking

gmgnai/gmgn-skills

Create and launch meme coins on Solana, BSC, and Base launchpads via bonding curve fair launch.

5.2k installs