0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

はじめに

前回までの続きです。今回はDomainServieでポケモンバトルを実装していきます。

ソースコード

ディレクトリ構成
├── domain
│   ├── entities
│   │   ├── move.dart
│   │   ├── pokemon.dart
│   │   └── stats.dart
│   ├── enums
│   │   └── pokemon_type.dart
│   ├── repositories
│   │   └── pokemon_repository.dart
│   └── services
│       └── battle_service.dart
lib/domain/services/battle_service.dart
import '../repositories/pokemon_repository.dart';
import '../entities/pokemon.dart';
import '../entities/move.dart';

class BattleService {
  final PokemonRepository _repository;

  // 名前付きパラメータを定義
  BattleService({required PokemonRepository repository})
      : _repository = repository;

  Future<void> startBattle(String name1, String name2) async {
    final pokemon1 = await _repository.getPokemon(name1);
    final pokemon2 = await _repository.getPokemon(name2);
    print('Battle started between ${pokemon1.name} and ${pokemon2.name}');
    // バトルロジックをここに追加
  }

  void useMove(Pokemon attacker, Pokemon defender, Move move) {
    print('${attacker.name} uses ${move.name} on ${defender.name}');
    // ダメージ計算やその他のバトルロジックをここに追加
  }

  void calculateDamage(Pokemon attacker, Pokemon defender, Move move) {
    // 簡単なダメージ計算ロジック
    int damage = (move.power * attacker.stats.attack) ~/ defender.stats.defense;
    print('${defender.name} receives $damage damage');
    // ここで防御側のHPを減らすロジックを追加する
  }
}

コンストラクタでインスタンスを作成。インスタンスに紐づくデータアクセスを実現している。

テストコードの実装

test/domain/services/battle_service_test.dart
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:mockito/annotations.dart';
import 'package:pokemon_battle_app/domain/entities/move.dart';
import 'package:pokemon_battle_app/domain/entities/pokemon.dart';
import 'package:pokemon_battle_app/domain/entities/stats.dart';
import 'package:pokemon_battle_app/domain/enums/pokemon_type.dart';
import 'package:pokemon_battle_app/domain/repositories/pokemon_repository.dart';
import 'package:pokemon_battle_app/domain/services/battle_service.dart';

import 'battle_service_test.mocks.dart';

@GenerateMocks([PokemonRepository])
void main() {
  group('BattleService', () {
    final mockRepository = MockPokemonRepository();
    final battleService = BattleService(repository: mockRepository);

    final pikachu = Pokemon(
      name: 'Pikachu',
      imageUrl:
          'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/25.png',
      moves: [Move(name: 'Thunderbolt', power: 90)],
      stats: Stats(hp: 35, attack: 55, defense: 40, speed: 90),
      type: PokemonType.electric,
    );

    final charmander = Pokemon(
      name: 'Charmander',
      imageUrl:
          'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/4.png',
      moves: [Move(name: 'Flamethrower', power: 90)],
      stats: Stats(hp: 39, attack: 52, defense: 43, speed: 65),
      type: PokemonType.fire,
    );

    setUp(() {
      // setUp関数内でモックの設定を行う
      when(mockRepository.getPokemon('Pikachu'))
          .thenAnswer((_) async => pikachu);
      when(mockRepository.getPokemon('Charmander'))
          .thenAnswer((_) async => charmander);
    });

    test('should start a battle and print the correct message', () async {
      await battleService.startBattle('Pikachu', 'Charmander');

      verify(mockRepository.getPokemon('Pikachu')).called(1);
      verify(mockRepository.getPokemon('Charmander')).called(1);
      // コンソール出力の検証は通常のユニットテストでは行いませんが、
      // 必要であれば `print` のモックを作成することもできます
    });

    test('should use a move and print the correct message', () {
      battleService.useMove(pikachu, charmander, pikachu.moves.first);
      // コンソール出力の検証は通常のユニットテストでは行いませんが、
      // 必要であれば `print` のモックを作成することもできます
    });

    test('should calculate damage correctly', () {
      battleService.calculateDamage(pikachu, charmander, pikachu.moves.first);
      // コンソール出力の検証は通常のユニットテストでは行いませんが、
      // 必要であれば `print` のモックを作成することもできます
    });
  });
}

今回はMockを利用しています。Mockはbuild_runner: ^2.1.11で作るので、事前にインストールしてください。
その後は、flutter pub run build_runner buildでMockが作成できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?