I'm implementing a API project on .net core, the solution follows simple three layer architecture as described below.
- Orders.Api --> Function App that implements controllers, security, exception handler, etc.
- Orders.Service --> Class library that implements all business logic (validations, application flow, models, etc)
- Orders.Repository --> Class library that implements repos to INFRA like database, service bus, etc.
One of Api (POST Orders) is implemented as shown below.
public class OrdersController
{
private readonly IHttpTriggerHelper _httpTriggerHelper;
private readonly IOrderService _OrderService;
public OrdersController(IHttpTriggerHelper httpTriggerHelper, IOrderService OrderService)
{
_httpTriggerHelper = httpTriggerHelper;
_OrderService = OrderService;
}
[Function("CreateOrder")]
public async Task<HttpResponseData> CreateOrder([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "dealers/{dealerId:int}/Orders")] HttpRequestData req, int dealerId)
{
var OrderRequest = await _httpTriggerHelper.GetRequestModel<OrderData>(req, cancellationToken);
var userId = _httpTriggerHelper.GetContextData(req, "User.Id") ?? string.Empty;
var OrderResponse = await _OrderService.SendOrderRequest(dealerId, userId, OrderRequest, cancellationToken);
return await _httpTriggerHelper.GetHttpResponse(OrderResponse, HttpStatusCode.Accepted, req, cancellationToken);
}
}
public class OrderService : IOrderService
{
private readonly IOrderRepository _orderRepository;
private readonly IValidationManager _validator;
public OrderService(IOrderRepository orderRepository, IValidationManager validator)
{
_orderRepository = orderRepository;
_validator = validator;
}
public async Task<OrderResponse> SendOrderRequest(int dealerId, string userId, OrderData? orderData)
{
_validator.ValidateOrderRequest(orderData);
orderData.EnrichWithRequestContextData(dealerId, userId);
await _orderRepository.SendOrderRequest(orderData);
return new OrderResponse { CorrelationId = orderData.CorrelationId, Status = orderData.Status };
}
}
I'm struggling to scope the contract and unit testing for OrderService.SendOrderRequest.
Here is my first approach on unit testing scope.
OrderService
must validate theorderData
(Ensure validate method is called)orderData
is enriched with request context data.orderData
is stored withorderRepository
.OrderResponse
is built as expected.
Here is my second approach on unit testing scope.
OrderService
must validate theorderData
(Ensure validate method is called)OrderService
must throw exception when theorderData
is not valid.orderData
is enriched with request context data.orderData
is stored withorderRepository
.OrderService
must throw exception when the failed to store theorderData
.OrderResponse
is built as expected.
The second approach seems to make the OrderService
more robust. The question I've is on the points 2 and 5.
- Is it a general/good practice to unit test all possible exceptions thrown from dependencies?
- If so, this expectation is also applicable to upper layers (ex; Api controller)?
Please share if any other better approaches also.
Aucun commentaire:
Enregistrer un commentaire