【Java】Guavaの@VisibleForTestingの利点は何?!同パッケージ内に公開したい!テストで活用すべし!

Guavaの「@VisibleForTesting」はGoogle Guavaライブラリで提供されているアノテーションの一種です

コードの可読性とメンテナンス性を向上させることです。以下はその利点のいくつかです

テスト専用メソッドの明示的な表示

@VisibleForTestingを使用することで、特定のメソッドやフィールドがテスト目的でのみ使用されることが明示的になります
これにより、コードを読む開発者は、それが本番コードの一部ではなく、主にテストのために存在していることを理解しやすくなります

APIのクリーンネス

クラスやメソッドが提供する公開APIがテストのために一時的に変更されることがあります
しかし、これらの変更は通常本番コードには影響を与えたくないです
@VisibleForTestingを使用すると、テストでのみ公開されるメンバーがあることがわかり、本番コードへの影響を最小限に抑えられます

外部のクラスからの利用の防止

@VisibleForTestingが付いたメンバーは通常の利用のために意図されていないことがわかります
外部のクラスやパッケージからの利用を防ぐことで、コードの安全性を向上させます

自己文書化

コードが自己文書化されると、開発者がコードを理解しやすくなります
@VisibleForTestingは、テスト目的でのみ使用されるメンバーがどれであるかを明示的に示す手段となります

テストの安定性の向上

ビジネスロジックとテストコードが分離され、テスト用のメソッドやフィールドが印刷されている場合、ビジネスロジックの変更がテストコードに影響を与える可能性が低くなります
これにより、テストの安定性が向上します

以下は、privateメソッドに@VisibleForTestingアノテーションを使用する具体的な例です

import com.google.common.annotations.VisibleForTesting;

public class MyClass {

    public int publicMethod() {
        // ビジネスロジックの実装
        return privateMethod() * 2;
    }

    @VisibleForTesting
    private int privateMethod() {
        // テストでのみ使用されるメソッドの実装
        return 42;
    }
}

この例では、privateMethodメソッドが@VisibleForTestingアノテーションを使用しています

これにより、このメソッドが通常のビジネスロジックの一部ではなく、テストのために公開されていることが明示されています

⇓ テストコード例

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class MyClassTest {

    @Test
    public void testPublicMethod() {
        MyClass myClass = new MyClass();
        int result = myClass.publicMethod();

        // ビジネスロジックが期待通りに動作しているか検証
        assertEquals(84, result);
    }

    @Test
    public void testPrivateMethod() {
        MyClass myClass = new MyClass();
        int result = myClass.privateMethod();

        // テストでのみ使用されるメソッドが期待通りに動作しているか検証
        assertEquals(42, result);
    }
}

このテストコードではMyClasspublicMethodメソッドとprivateMethodメソッドがそれぞれ期待通りに動作しているかを検証しています

privateMethodメソッドは@VisibleForTestingアノテーションを使用しているため、テストコードからもアクセス可能です

ぜひ活用してみてください!!

ではっ

import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import javax.crypto.Mac;
import java.security.NoSuchAlgorithmException;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

class MacStaticTest {

    @Test
    void testGetInstanceThrowsException() {
        // staticメソッドをモック化
        try (MockedStatic<Mac> macMockedStatic = Mockito.mockStatic(Mac.class)) {
            // getInstanceが呼ばれたら例外を投げるように設定
            macMockedStatic.when(() -> Mac.getInstance("HmacSHA256"))
                    .thenThrow(new NoSuchAlgorithmException("No such algorithm"));

            // 例外が投げられることを確認
            Exception exception = assertThrows(NoSuchAlgorithmException.class, () -> {
                Mac.getInstance("HmacSHA256");
            });

            assertEquals("No such algorithm", exception.getMessage());
        }
    }
}

是非フォローしてください

最新の情報をお伝えします