Skip to content

AddNewOrder in Ordering.FunctionalTests is not properly tested #943

@mwakayama

Description

@mwakayama

eshop.Ordering.FunctionalTests.OrderingApiTests.AddNewOrder in the Ordering.FunctionalTest project cannot be considered properly tested for the following reasons.

1. Parameters that cause validation errors are being passed

The POST api/orders API receives a CreateOrderRequest.
An instance of this class is converted into IdentifiedCommand<CreateOrderCommand> and passed to mediator.Send.

However, due to eShop.Ordering.API.Application.Validations.CreateOrderCommandValidator, a validation error occurs when the command is sent.

Because of the following code in IdentifiedCommandHandler, validation errors for CreateOrderCommand are caught by exception handling, and the return value of the Handle method becomes false (since the method returns default for a bool return type).

var result = await _mediator.Send(command, cancellationToken);

    var result = await _mediator.Send(command, cancellationToken);

    _logger.LogInformation(
        "Command result: {@Result} - {CommandName} - {IdProperty}: {CommandId} ({@Command})",
        result,
        commandName,
        idProperty,
        commandId,
        command);

    return result;
}
catch
{
    return default;
}

As a result, even when mediator.Send returns false, the POST api/orders API still returns 200 OK, causing the test to pass incorrectly.

var result = await services.Mediator.Send(requestCreateOrder);

if (result)
{
    services.Logger.LogInformation("CreateOrderCommand succeeded - RequestId: {RequestId}", requestId);
}
else
{
    services.Logger.LogWarning("CreateOrderCommand failed - RequestId: {RequestId}", requestId);
}

return TypedResults.Ok();

2. A Microsoft.EntityFrameworkCore.DbUpdateException occurs because cardExpirationDate.Kind is Kind.Local

(This issue may be environment-dependent.)

If issue 1 is fixed so that validation succeeds, AddNewOrder fails due to an exception.

var cardExpirationDate = Convert.ToDateTime("2123-12-22T12:34:24.334Z");
var OrderRequest = new CreateOrderRequest(
    UserId: "1",
    UserName: "TestUser",
    City: "test city",
    Street: "test street",
    State: "test state",
    Country: "test country",
    ZipCode: "00001",
    CardNumber: "XXXXXXXXXXXX0005",
    CardHolderName: "Test User",
    CardExpiration: cardExpirationDate,
    CardSecurityNumber: "000",
    CardTypeId: 1,
    Buyer: "TestBuyer",
    Items: new List<BasketItem> { item });

When writing DateTime values to PostgreSQL, the Kind must be Kind.Utc.
However, since cardExpirationDate is initialized as shown above, its Kind becomes Kind.Local, which is presumed to be the cause of the exception.

If the code is changed as follows, the exception does not occur:

var cardExpirationDate = DateTime.Parse(
    "2123-12-22T12:34:24Z",
    null,
    System.Globalization.DateTimeStyles.AdjustToUniversal);

3. IntegrationEventLogService fails to deserialize EventLogEntry when publishing OrderStartedIntegrationEvent

After fixing issue 2, another issue arises.
This may be better handled as a separate issue.

Because derived classes of IntegrationEvent are not included in the FunctionalTest assembly, the following code in
eshop.IntegrationEventLogEF.Services.IntegrationEventLogService<TContext> results in an empty array:

_eventTypes = Assembly.Load(Assembly.GetEntryAssembly().FullName)

// In FunctionalTests, the Entry Assembly is the DLL built from the test project.
// Derived IntegrationEvent classes do not exist there.
_eventTypes = Assembly.Load(Assembly.GetEntryAssembly().FullName)
    .GetTypes()
    .Where(t => t.Name.EndsWith(nameof(IntegrationEvent)))
    .ToArray();

Since _eventTypes is an empty array, RetrieveEventLogsPendingToPublishAsync in the same class fails at the following code:

.Select(e => e.DeserializeJsonContent(_eventTypes.FirstOrDefault(t => t.Name == e.EventTypeShortName)));

// Since _eventTypes is empty, a NullReferenceException occurs
return result.OrderBy(o => o.CreationTime)
    .Select(e => e.DeserializeJsonContent(
        _eventTypes.FirstOrDefault(t => t.Name == e.EventTypeShortName)));

I checked other tests but could not find any others that publish IntegrationEvents.
Therefore, it is fair to say that tests involving the publication of integration events are not properly covered by FunctionalTests.

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