Unit testing code that uses a launcher or chooser directly is a challenge because both types of tasks cause your app to be deactivated. No means to abstract launchers or choosers exists out-of-the-box; therefore, I have included in the downloadable sample code a set of classes that do just that.
Just as we abstracted the built-in LicenseInformation
class in the previous section, here we do the same with the MarketDetailTask
. The MarketDetailTask
is a launcher which, when shown, takes the user to the built-in marketplace application. When showing the MarketplaceDetailTask
during a debugging session, the native marketplace application displays an error because it expects an app with an id that has been officially published to the marketplace.
The main issue, however, is that when the MarketplaceDetailTask
is shown, it deactivates the app. Thus, it makes sense to abstract the task as in the LicenseInformation
class in the previous section.
The abstracted custom interface for the MarketplaceDetailTask
is named IMarketDetailTask
and contains a single method named Show
. There are two implementations of this interface. The first, named MarketplaceDetailTaskAdapter
, calls the Show
method of a built-in MarketplaceDetailTask
instance when its own Show
method is called, as shown in the following excerpt:
public class MarketplaceDetailTaskAdapter : IMarketplaceDetailTask
{
public void Show()
{
var marketplaceDetailTask = new MarketplaceDetailTask();
marketplaceDetailTask.Show();
}
}
The unit test compatible implementation of the IMarketplaceDetailTask
is called MockMarketplaceDetailTask
and allows a specified Action
to be invoked when the Show
method is called:
public class MockMarketplaceDetailTask : IMarketplaceDetailTask
{
readonly Action action;
public MockMarketplaceDetailTask(Action action)
{
this.action = action;
}
public void Show()
{
if (action != null)
{
action();
}
}
}
The ChatClientViewModel
class contains an ICommand
named BuyCommand
, which, when executed, retrieves the IMarketplaceDetailTask
from the IoC container and calls its Show
method. BuyCommand
is initialized in the viewmodel’s constructor, as shown:
buyCommand = new DelegateCommand(
obj =>
{
var marketplaceDetailTask
= Dependency.Resolve<IMarketplaceDetailTask>();
marketplaceDetailTask.Show();
});
When the BuyCommand
is executed, it causes the IMarketDetailTask
instance to be resolved using the static Dependency.Resolve
method. Recall that a particular implementation of the IMarketDetailTask
is registered according to the selected build configuration, as described in the earlier section “A Custom IoC Container and DI Framework.” If the build is using a Release configuration, an instance of the MarketplaceDetailTaskAdapter
is resolved, which, in turn, causes an instance of the built-in MarketplaceDetailTask
to be shown. Conversely, if the build is using a Debug configuration, the MockMarketplaceDetailTask
is used, which does not disrupt unit testing or any manual ad hoc testing.
18.117.187.62