(調査中)Spring MVC コントローラで、テストメソッド毎に異なる実際のプロパティファイルを参照

## 1. @TestPropertySource と @DirtiesContext を組み合わせる方法

この方法では、@TestPropertySource アノテーションを使用して、テストメソッド毎に異なるプロパティファイルを指定し、@DirtiesContext アノテーションでコンテキストをリロードします。

```java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.annotation.DirtiesContext;

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @TestPropertySource(locations = "classpath:test-application-method1.properties")
    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
    public void testMethod1() throws Exception {
        mockMvc.perform(get("/some-endpoint"))
               .andExpect(status().isOk());
    }

    @Test
    @TestPropertySource(locations = "classpath:test-application-method2.properties")
    @DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD)
    public void testMethod2() throws Exception {
        mockMvc.perform(get("/another-endpoint"))
               .andExpect(status().isOk());
    }
}
```

## 2. 動的にプロパティを設定する方法

テストメソッドの実行前にプロパティを動的に設定するために、DynamicPropertySource を使用する方法です。各メソッドの前に設定を変更するためのカスタムロジックを追加します。

TestPropertySource のカスタム拡張

```java
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.support.TestPropertySourceUtils;
import org.springframework.core.io.ClassPathResource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class DynamicPropertiesExtension implements BeforeEachCallback {
    @Override
    public void beforeEach(ExtensionContext context) throws Exception {
        TestProperties testProperties = context.getRequiredTestMethod().getAnnotation(TestProperties.class);
        if (testProperties != null) {
            for (String propertyFile : testProperties.value()) {
                addPropertiesFromFile(propertyFile, context);
            }
        }
    }

    private void addPropertiesFromFile(String propertyFile, ExtensionContext context) throws IOException {
        Path path = new ClassPathResource(propertyFile).getFile().toPath();
        Files.lines(path)
             .filter(line -> !line.startsWith("#") && line.contains("="))
             .forEach(line -> {
                 String[] keyValue = line.split("=", 2);
                 System.setProperty(keyValue[0], keyValue[1]);
             });
    }
}

```

カスタムアノテーションの定義

```java
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;
import org.junit.jupiter.api.extension.ExtendWith;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@ExtendWith(DynamicPropertiesExtension.class)
public @interface TestProperties {
    String[] value();
}

```

テストクラスでの使用

```java
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;

@ExtendWith(SpringExtension.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @TestProperties("test-application-method1.properties")
    public void testMethod1() throws Exception {
        mockMvc.perform(get("/some-endpoint"))
               .andExpect(status().isOk());
    }

    @Test
    @TestProperties("test-application-method2.properties")
    public void testMethod2() throws Exception {
        mockMvc.perform(get("/another-endpoint"))
               .andExpect(status().isOk());
    }
}

```

詳細説明
@DirtiesContext: 各テストメソッドの前にアプリケーションコンテキストをリロードし、設定の再読み込みを行います。
DynamicPropertiesExtension: 各テストメソッドの実行前にプロパティファイルを読み込み、その内容をシステムプロパティに設定します。
TestProperties: テストメソッドごとに異なるプロパティファイルを指定するためのカスタムアノテーションです。
このアプローチを使用することで、テストメソッドごとに異なるプロパティファイルを適用し、プロパティ設定を動的に切り替えることができます。