{ @Test void updateTaskTest() { // given TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); }
updateTaskTest() { // given TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); } Application層の単体テスト 2. 統合テストの基礎知識 更新対象のデータを 内部的に取得するスタブを定義
updateTaskTest() { // given TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); } Application層の単体テスト 2. 統合テストの基礎知識 処理をコール
updateTaskTest() { // given TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); } Application層の単体テスト 2. 統合テストの基礎知識 モックとして意図したデータで update処理を呼んだか検証
// given TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); } ID1でTaskRepositoryの findByを呼んだらID1のタスクを 返してほしい。 その上でID1のタスクを更新したい
TaskRepository taskRepository = mock(TaskRepository.class); Task task = new Task(1, "title", "description"); when(taskRepository.findById(task.id())).thenReturn(Optional.of(task)); // when UpdateTaskUseCase updateTaskUseCase = new UpdateTaskUseCase(taskRepository); updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then verify(taskRepository).update(new Task(1, "new title", "new description")); } 2. 統合テストの基礎知識 TaskRepositoryのupdate が意図した引数で呼ばれた!
{ // given Task task = new Task("title", "description"); taskRepository.insert(task); // when updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then Task updatedTask = taskRepository.findById(task.id()).get(); Assertions.assertEquals("new title", updatedTask.title()); Assertions.assertEquals("new description", updatedTask.description()); }
{ // given Task task = new Task("", ""); taskRepository.insert(task); // when updateTaskUseCase.execute( new UpdateTaskCommand(task.id(), "new title", "new description") ); // then Task updatedTask = taskRepository.findById(task.id()).get(); Assertions.assertEquals("new title", updatedTask.title()); Assertions.assertEquals("new description", updatedTask.description()); } 空文字でタスクを作ろうとすると この時点でエラーになる。
() { // given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new Task( user.id(), "title", "description", List.of("image1", "image2") ); taskRepository.insert(task); // when … // then … }
given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new Task( user.id(), "title", "description", List.of("image1", "image2") ); taskRepository.insert(task); // when … // then … } 4. モデルベースのテストフィクスチャ テスト観点に関係のない項目 暗黙的なGiven
given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new Task( user.id(), "title", "description", List.of("image1", "image2") ); taskRepository.insert(task); // when … // then … } 4. モデルベースのテストフィクスチャ テスト観点に関係のないデータ 暗黙的なGiven
given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new Task( user.id(), "title", "description", List.of("image1", "image2") ); taskRepository.insert(task); // when … // then … } 4. モデルベースのテストフィクスチャ ただタスクがあればいい 明示的なGiven
given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new TaskTestBuilder().userId(user1Id).build(); taskRepository.insert(task); // when … // then … } 4. モデルベースのテストフィクスチャ テスト観点に関係しない項目をテスト から隠す • Javaのビルダーパターンを使 い項目をデフォルト値で埋める ようにする
given Task task = new TaskTestBuilder() .userId(UserTestSeedData.user1Id) .build(); taskRepository.insert(task); // when … // then … } 4. モデルベースのテストフィクスチャ @Test void タスクを更新できること() { // given User user = new User(1, "name", "[email protected]"); userRepository.insert(user); Task task = new Task(user.id(), "title", "description", List.of("image1", "image2")); taskRepository.insert(task); // when … // then … }