シーンの説明
Spring プロジェクトではログを収集するように Logback が構成され、単体テストには @SpringBootTest が使用されます。この時点で、エラーが報告され、ファイルが見つかりませんでした。
ch.qos.logback.core.rolling.RollingFileAppender[file] のエラー - [/home/zhu/app/logs/2022-09-07.log] の親ディレクトリの作成に失敗しました
ch.qos.logback.core のエラー.rolling.RollingFileAppender[file] - openFile(null,true) 呼び出しが失敗しました。java.io.FileNotFoundException: /home/zhu/app/logs/2022-09-07.log (そのようなファイルまたはディレクトリはありません)
理由
logback-spring.xml
これはファイルに記述されており、 bosc.rec.logSavePath でログファイルの保存を指定します。これはapplication.yml
で指定できます。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="false" packagingData="true">
<springProperty scope="context" name="LOG_HOME" source="bosc.rec.logSavePath" />
<!-- 中间内容省略了 -->
</configuration>
# application.yml
bosc:
rec:
logSavePath: ${
LOG_SAVE_PATH:/home/zhu/app/logs}
単体テストが開始されると、最初にログバック構成がロードされ、次にテスト ケースが実行されます。ログ ファイルが見つからない場合は、上記の例外がスローされます。さらに、環境変数を内部的に使用@Before
または設定しても@BeforeAll
問題は解決できません。これらのメソッドの実行は、ログバック構成のロードよりも遅いためです。static
System.setProperty()
解決
コードに直接移動します。
public class PropertyExtension implements BeforeAllCallback {
@Override
public void beforeAll(ExtensionContext context) {
System.setProperty("LOG_SAVE_PATH", "/Users/mac/Downloads/bosc/logs");
}
}
@ExtendWith(PropertyExtension.class)
@SpringBootTest(classes = JobManageApplication.class)
class ScenePipelineRepositoryImplTest {
@Autowired
ScenePipelineRepository repository;
@Test
public void save_ScenePipeline_succeed() {
// 内容省略
}
一言
例外がスローされる理由は、@SpringBootTest が単体テストに使用されているためです。このアノテーションは、テスト ケースの実行時に Spring サービス全体を開始するため、Spring の初期化プロセスが実行され、ログバックを含む多くのものが読み込まれます。 。
しかし、この使用法は不合理です。
理由 1: 1 つのテストでは 1 つの機能ポイントのみがテストされますが、サービス全体を開始する必要がありますか? 統合テストの話ではありません。
理由 2: サービスにスケジュールされたタスクや他のサービスにリクエストを送信する機能がある場合、そのタスクも実行されるため、単一のテストでは発生したくない現象です。
@SpringBootTest は統合テストに適しており、テストが成功したら @ignore を使用してテスト クラスにアノテーションを付けます。
Spring は 3 層構造になっており、各層に 1 つのテストがあり、各層でのテストの目的や方法が異なります。
チームメンバーに特定のルールに従ってもらうのは難しい場合があります。