planetarium / mimir

A backend service that provides 9c-related utility APIs.
https://nine-chronicles.dev/
GNU Affero General Public License v3.0
5 stars 22 forks source link

Add integration Test for Mimir Balance Query #520

Open Atralupus opened 4 days ago

Atralupus commented 4 days ago

We need to add unit tests for the Balance query to ensure it works as expected for different currencyTicker values and properly handles missing inputs.


Create BalanceQueryTest.cs with Initial integration Tests

public class BalanceQueryTest
{
    [Fact]
    public async Task GraphQL_Query_Balance_CRYSTAL_Returns_CorrectValue()
    {
    }

    [Fact]
    public async Task GraphQL_Query_Balance_NCG_Returns_CorrectValue()
    {
    }

    [Fact]
    public async Task GraphQL_Query_Balance_Throws_When_No_Inputs_Provided()
    {
    }
}

Mocking IServiceProvider with Mock BalanceRepository

  1. Create IBalanceRepository Interface:

    • Add the IBalanceRepository interface and apply it to BalanceRepository.
  2. Make BalanceRepository.GetByAddressAsync Virtual:

    • Modify the GetByAddressAsync method to be virtual to allow mocking.
  3. Mock the Repository for Different Scenarios:

    [Fact]
    public async Task GraphQL_Query_Balance_CRYSTAL_Returns_CorrectValue()
    {
    var mockAddress = new Address("0x0000000000000000000000000000000000000000");
    var mockRepo = new Mock<IBalanceRepository>();
    
    mockRepo
        .Setup(repo => repo.GetByAddressAsync("CRYSTAL".ToCurrency(), mockAddress))
        .ReturnsAsync(new Balance { Currency = "CRYSTAL", Address = mockAddress, Amount = 100 });
    
    var serviceProvider = TestServices.CreateServices(balanceRepositoryMock: mockRepo);
    
    var query = $$"""
        query {
          balance(currencyTicker: "CRYSTAL", address: "{{mockAddress}}")
        }
    """;
    
    var result = await TestServices.ExecuteRequestAsync(serviceProvider, b => b.SetQuery(query));
    
    await Verify(result);
    }

Add Test for NCG Query

[Fact]
public async Task GraphQL_Query_Balance_NCG_Returns_CorrectValue()
{
    var mockAddress = new Address("0x0000000000000000000000000000000000000000");
    var mockRepo = new Mock<IBalanceRepository>();

    mockRepo
        .Setup(repo => repo.GetByAddressAsync("NCG".ToCurrency(), mockAddress))
        .ReturnsAsync(new Balance { Currency = "NCG", Address = mockAddress, Amount = 200 });

    var serviceProvider = TestServices.CreateServices(balanceRepositoryMock: mockRepo);

    var query = $$"""
        query {
          balance(currencyTicker: "NCG", address: "{{mockAddress}}")
        }
    """;

    var result = await TestServices.ExecuteRequestAsync(serviceProvider, b => b.SetQuery(query));

    await Verify(result);
}

Add Test for Missing Inputs (Exception Handling)

[Fact]
public async Task GraphQL_Query_Balance_Throws_When_No_Inputs_Provided()
{
    var mockRepo = new Mock<IBalanceRepository>();
    var serviceProvider = TestServices.CreateServices(balanceRepositoryMock: mockRepo);

    var query = $$"""
        query {
          balance(address: "0x0000000000000000000000000000000000000000")
        }
    """;

    var exception = await Assert.ThrowsAsync<GraphQLRequestException>(
        async () => await TestServices.ExecuteRequestAsync(serviceProvider, b => b.SetQuery(query))
    );

    Assert.Contains("Either currency or currencyTicker must be provided.", exception.Message);
}

Notes

  1. Use Verify:

    • The Verify method ensures that the returned GraphQL response matches the expected snapshot, simplifying validation of nested or complex structures.
  2. Scenarios Tested:

    • Query with currencyTicker = "CRYSTAL".
    • Query with currencyTicker = "NCG".
    • Exception when neither currency nor currencyTicker is provided.
  3. Mocking:

    • The repository is mocked to isolate the test from dependencies, ensuring it focuses solely on the query's behavior.
  4. Additional Input (CurrencyInput):

    • Tests for CurrencyInput are excluded as per your requirements but can be added later.
sonshn commented 3 days ago

Please assign this issue to me!

boscohyun commented 3 days ago

@sonshn For sure!

sonshn commented 3 days ago

Sorry, please unassign this issue from me!

boscohyun commented 3 days ago

@sonshn OK. never mind and thanks!😊