Possibility to instantiate ResolvedSubscription in tests
piotr-consensus opened this issue · 0 comments
Hi Team!
Is your feature request related to a problem? Please describe.
We forked the Commercial-Marketplace-SaaS-Accelerator project which references commercial-marketplace-client-dotnet library. I'm in the process of adding some integration tests to our fork, where I'd like to mock out IMarketplaceSaaSClient
because (as far as I understand, please correct me if I'm wrong) it is the component accessing the "real" Fulfillment API.
So basically I'm trying to mock out this line from FulfillmentApiService
in Commercial-Marketplace-SaaS-Accelerator:
var resolvedSubscription = (await this.marketplaceClient.Fulfillment.ResolveAsync(marketPlaceAccessToken)).Value;
This proves difficult because of the IMarketplaceSaaSClient.Fulfillment
property:
public interface IMarketplaceSaaSClient
{
FulfillmentOperations Fulfillment { get; }
SubscriptionOperations Operations { get; }
}
It is of concrete class type and not an interface. That in itself is not a problem, I can set mock of IMarketplaceSaaSClient
to return mock (so a sub-class) of FulfillmentOperations
, which in turn returns a mock of Response<ResolvedSubscription>
from FulfillmentOperations.ResolveAsync(...)
method (wrapped in Task
of course) thanks to the fact that this method is virtual.
What I cannot do is create a real instance or mock of ResolvedSubscription
itself, as all of its constructors (including parameterless) are internal
. Because of that I cannot set up the FulfillmentOperations.ResolveAsync(...)
method to return anything in the mentioned line of code
var resolvedSubscription = (await this.marketplaceClient.Fulfillment.ResolveAsync(marketPlaceAccessToken)).Value;
Describe the solution you'd like
Currently the workaround would be to isolate entire class making use of IMarketplaceSaaSClient
(so in the Accelerator project that's FulfillmentApiService
, but that reduces code coverage as it skips code included in our fork, which we control now.
What I would prefer is ability to instantiate whatever gets returned from IFulfillmentOperations.ResolveAsync(...)
, so if e.g. that method's signature was changed from
public virtual async Task<Response<ResolvedSubscription>> ResolveAsync(
string xMsMarketplaceToken,
Guid? requestId = null,
Guid? correlationId = null,
CancellationToken cancellationToken = default (CancellationToken))
to
public virtual async Task<Response<IResolvedSubscription>> ResolveAsync(
string xMsMarketplaceToken,
Guid? requestId = null,
Guid? correlationId = null,
CancellationToken cancellationToken = default (CancellationToken))
i.e. ResolvedSubscritpion
would get an interface extracted, and that interface would be used in return type of ResolveAsync
instead.
Describe alternatives you've considered
Alternatively one of the constructors on ResolvedSubscription
could be made public so I could instantiate this class in tests.
Additional context
As extra convenience, maybe it would be possible to change
public interface IMarketplaceSaaSClient
{
FulfillmentOperations Fulfillment { get; }
SubscriptionOperations Operations { get; }
}
to
public interface IMarketplaceSaaSClient
{
IFulfillmentOperations Fulfillment { get; }
ISubscriptionOperations Operations { get; }
}
seeing that both FulfillmentOperations
and SubscriptionOperations
already have those interfaces.
Thanks for your consideration, and please let me know if anything needs any extra info.