Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expressionの値をテストする #2127

Open
tsuna-can-se opened this issue Dec 9, 2024 · 3 comments
Open

Expressionの値をテストする #2127

tsuna-can-se opened this issue Dec 9, 2024 · 3 comments
Assignees
Labels
not triaged 精緻化、分析がされていない target: Dressca サンプルアプリケーションDresscaに関係がある

Comments

@tsuna-can-se
Copy link
Contributor

概要

現状の単体テストでは、リポジトリに渡される検索条件が単体テストの中で確認されていない。
例えば samples/Dressca/dressca-backend/tests/Dressca.UnitTests.ApplicationCore/ApplicationService/CatalogApplicationServiceTest.cs では以下のように実装されている。

    [Fact]
    public async Task GetCatalogItemsAsync_リポジトリのFindAsyncを1回呼出す()
    {
        // Arrange
        var catalogRepositoryMock = new Mock<ICatalogRepository>();
        var catalogBrandRepository = Mock.Of<ICatalogBrandRepository>();
        var catalogCategoryRepository = Mock.Of<ICatalogCategoryRepository>();
        var logger = this.CreateTestLogger<CatalogApplicationService>();
        var service = new CatalogApplicationService(catalogRepositoryMock.Object, catalogBrandRepository, catalogCategoryRepository, logger);
        const int skip = 1;
        const int take = 10;

        // Act
        _ = await service.GetCatalogItemsAsync(skip, take, 1, 1);

        // Assert
        catalogRepositoryMock.Verify(
            r => r.FindAsync(It.IsAny<Expression<Func<CatalogItem, bool>>>(), skip, take, AnyToken),
            Times.Once);
    }

Assertする際、検索条件の検証が It.IsAny<Expression<Func<CatalogItem, bool>>>() で行われており、適切に検索条件がテストされているとは言えない。
検索条件が正しく設定されているかテストする必要がある。

詳細 / 機能詳細(オプション)

対象のテストを明らかにしてから着手する必要がある。
必要に応じて Sub-issue を作成して、少しずつ対処する。

完了条件

  • リポジトリに検索条件を引き渡す個所で、適切な検索条件が渡されているか単体テストの中で確認できていること
@tsuna-can-se tsuna-can-se added not triaged 精緻化、分析がされていない target: Dressca サンプルアプリケーションDresscaに関係がある labels Dec 9, 2024
@fkoyama fkoyama self-assigned this Jan 9, 2025
@fkoyama
Copy link
Contributor

fkoyama commented Jan 14, 2025

Repositoryメソッドに引数として渡すExpression の値が正確に検証できていないテストケース

  • CatalogApplicationServiceTest

    • GetCatalogItemsAsync_リポジトリのFindAsyncを1回呼出す()
    • GetCatalogItemsForAdminAsync_リポジトリのFindAsyncを一度だけ呼び出す()
    • GetCatalogItemsAsync_リポジトリのCountAsyncを1回呼出す()
    • GetCatalogItemsForAdminAsync_リポジトリのCountAsyncを1回呼出す()
  • ShoppingApplicationServiceTest

    • GetBasketItemsAsync_購入者Idがnullまたは空白ではない_カタログリポジトリのFindAsyncを1度だけ呼び出す()
    • CheckoutAsync_買い物かごにアイテムが存在する_カタログリポジトリのFindAsyncを1度だけ呼び出す()

※Expressionを引数に持つRepositoryメソッド
・ICatalogRepository.FindAsync()
・ICatalogRepository.CountAsync()

引数としてメソッドに渡されるExpressionの検証案

  • Repositoryのメソッドに引数としてExpressionを渡さないよう修正する
    ⇒Expressionの代わりにbrandId等の検索条件をRepositoryのメソッドに渡し、ExpresssionをRepository側で組み立て
- public async Task<IReadOnlyList<CatalogItem>> FindAsync(Expression<Func<CatalogItem, bool>> specification, int skip, int take, CancellationToken cancellationToken = default)
+ public async Task<IReadOnlyList<CatalogItem>> FindAsync(long? brandId, long? categoryId, int skip, int take, CancellationToken cancellationToken = default)

@fkoyama
Copy link
Contributor

fkoyama commented Jan 14, 2025

Repositoryメソッドの引数として渡されるオブジェクトの検証方針

  • アプリケーションサービスの業務ロジックによってリポジトリの引数として渡されるオブジェクトのプロパティに影響がある場合、正しく変更されているか確認する(突き詰めていくとエンティティの単体テストと重複する?)
  • 確認対象のプロパティごとにテストメソッドを作成する(※ Assert.Same() で検証できる場合はインスタンスごと)

上記の方針により、以下のテストに関して新たにテストを追加する必要があると考えられる。

  • ShoppingApplicationServiceTest
    • AddItemToBasketAsync_カタログリポジトリに存在するカタログアイテムが追加対象_買い物かごリポジトリのUpdateAsyncを1度だけ呼び出す()
      • basketRepository.UpdateAsync() の引数であるBasketのBuyerIdのみ確認しているため、追加対象の買い物かごアイテムが買い物かご内に存在していることを検証する
      • 新規追加テスト:AddItemToBasketAsync_カタログリポジトリに存在するカタログアイテムが追加対象_買い物かごに追加対象の商品が追加される
    • CheckoutAsync_買い物かごにアイテムが存在する_注文リポジトリのAddAsyncを1度だけ呼び出す()
      • orderRepository.AddAsync() の引数であるOrderのBuyerIdのみ確認している
      • 業務ロジック内ではOrderFactoryでOrderのインスタンスを生成しているため、Orderに正しくorderItems等のプロパティが設定されているかはOrderFactoryクラスのテストで行うべき(現在テストが存在しないので別Issueで対応)
      • ShoppingApplicationServiceのテストとしては、CheckOutAsync()の引数として渡されたShipToAddressがOrderに正しく設定されているかを検証する
      • 新規追加テスト:CheckoutAsync_買い物かごにお届け先が正しく設定されている

なお、以下のテストについては他のテストケースでカバーされているため新たなテストは実装不要と考えられる。

  • ShoppingApplicationServiceTest
    • SetBasketItemsQuantitiesAsync_買い物かご内とカタログリポジトリに存在するカタログアイテムが数量設定対象_買い物かごリポジトリのUpdateAsyncを1度だけ呼び出す()
      • 現状のテストコードではBasketのBuyerIdのみ確認
      • 買い物かごアイテムの数量を設定する業務ロジックを含むため、買い物かごアイテムごとに数量の検証も必要だが、
         SetBasketItemsQuantitiesAsync_買い物かご内とカタログリポジトリに存在するカタログアイテムが数量設定対象_買い物かごの商品数が更新される() にて実装済みのため、新たなテストは不要
  • CatalogApplicationService
    • AddItemToCatalogAsync_リポジトリのAddAsyncを一度だけ呼び出す()
      • 現状 It.IsAny<CatalogItem> でcatalogRepository.AddAsync()の引数としてCatalogItemのインスタンスが渡されていることを確認している
      • 業務ロジック内では受け取った引数をそのままCatalogItemのプロパティとして設定しているため、CatalogItemのプロパティの検証が必要だが、AddItemToCatalogAsync_追加したアイテムの情報が返却される()で検証しているため新たなテストは不要

@fkoyama
Copy link
Contributor

fkoyama commented Jan 17, 2025

未実装のRepository呼び出しを検証するテスト

  • OrderApplicationServiceTest
    • GetOrderAsync_注文リポジトリのGetWithBasketItemsAsyncを1度だけ呼び出す
  • AssetApplicationServiceTest
    • GetAssetStreamInfoAsync_アセットリポジトリのFindAsyncを1度だけ呼び出す
    • GetAssetStreamInfoAsync_アセットストアのGetStreamを1度だけ呼び出す
      ⇒別テストで戻り値のオブジェクトが等値であることを確認しているため追加不要
  • ShoppingApplicationService.GetBasketItemsAsync()
    • GetBasketItemsAsync_買い物かごリポジトリのFindAsyncを1度だけ呼び出す
    • GetBasketItemsAsync_購入者Idに対応する買い物かごが存在しない_買い物かごリポジトリのAddAsyncを1度だけ呼び出す

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not triaged 精緻化、分析がされていない target: Dressca サンプルアプリケーションDresscaに関係がある
Projects
None yet
Development

No branches or pull requests

2 participants