Skip to content

Dapper SplitOn-query throws exception when using DbMocker #41

@Krm1t

Description

@Krm1t

Hello

Before I begin I just wanna say thank you for making this project.
It's nice to be able to mock the DbConnection rather than having to create some class that holds all queries just because I need to mock out the database calls. I haven't used it much yet but so far it's been working great (except for this issue).

I don't know if this is a bug or just me being dense - Probably the latter.
I'm assuming this isn't a Dapper issue as the code works just fine when running the application.
It's only when i run the test that this fails.

So what am i doing?

The example is based on actual code but i've omitted quite a large chunk of the code/script as well as changing table/column names.
Please let me know if i omitted too much.

Consider the following code (ignore my poor choice in naming)

public record Order
{
  public required long OrderId { get; set; }
  public required string Name { get; set; }
  public Customer? Customer { get; set; }
}

public record Customer
{
  public required long Id { get; init; }
  public required string Name { get; init; }
}

public async Task<IEnumerable<Order>> RunQuery(CancellationToken cancellationToken = default)
{
  var sqlScript = $@"
SELECT o.OrderId, o.Name, c1.Id, c1.Name
FROM Order o
LEFT JOIN Customer c1 ON c1.Id = o.Customer1Id
";

  var commandDef = new CommandDefinition(
    sqlScript,
    cancellationToken: cancellationToken
    );

  return await _connection.QueryAsync<Order, Customer, Order>(
    commandDef,
    (order, c1) =>
    {
      order.Customer = c1;
      return order;
    }, splitOn: "Id");
}

The above code gives me a list of Order items where Customer may or may not be specified.
Then I create the following test.

[Fact]
public async Task Test1()
{
  var mockConnection = new MockDbConnection();

  mockConnection
    .Mocks
    .WhenAny()
    .ReturnsTable(cmd =>
    {
      var table = MockTable
        .WithColumns(
          ("OrderId", typeof(long)),
          ("Name", typeof(string)),
          ("Id", typeof(long?)),
          ("Name", typeof(string))
          )
        .AddRow([(long)1, "Some order name", (long?)2, "Name for c1"])
        .AddRow([(long)10, "Some order name", null, null]);
      return table;
    });

  var sut = new DapperSplitOnQuery(mockConnection);

  var result = await sut.RunQuery();
  Assert.NotNull(result);
}

When I run this test I get the following exception from Dapper:

System.Data.DataException: 'Error parsing column 2 (Id=<null>)'
Inner Exception
InvalidOperationException: Nullable object must have a value.

I've tried changing things left, right and, center but nothing worked and I've run out of ideas.
Am I doing something wrong in my setup or is there a bug somewhere in DbMocker?
As I mentioned earlier I'm assuming this is not a Dapper issue as the code works just fine when running the actual application.

Edit: I've tried casting null (3rd param on the second AddRow) to long? that didn't help.
Omitting the second AddRow makes the test work just fine so it is definitely related to the nullable Id column.

I do have a sample project but all the code has practically been shown above.

I hope someone has some insigt.

Regards
Kenneth

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions