Ok I actually managed to figure this out myself and I figure I would reply here in the event that someone else is trying to figure the same thing out.
The drawback to my approach is that I did have to add a bunch of classes/interfaces etc in order to successfully mock the AWS SNS calls to test my own code.
First I created 2 interfaces, and 2 classes for the Message and Validator
<?php
namespace OneThirtyOne\Sns\Concerns;
interface SnsMessageInterface
{
/**
* Get an instance of an SNS Message.
*
* @return \Aws\Sns\Message
*/
public function get();
/**
* Get a message Property.
*
* @param $property
*
* @return mixed
*/
public function __get($property);
}
<?php
namespace OneThirtyOne\Sns;
use OneThirtyOne\Sns\Concerns\SnsMessageInterface;
/**
* Class Message.
*/
class Message implements SnsMessageInterface
{
/**
* @var \Aws\Sns\Message
*/
protected $message;
/**
* Message constructor.
*/
public function __construct()
{
$this->message = \Aws\Sns\Message::fromRawPostData();
}
/**
* {@inheritdoc}
*/
public function get()
{
return $this->message;
}
/**
* {@inheritdoc}
*/
public function __get($property)
{
return $this->message[$property];
}
}
<?php
namespace OneThirtyOne\Sns\Concerns;
interface SnsValidatorInterface
{
/**
* Validate the incoming SNS Message.
*
* @param \Aws\Sns\Message $message
*
* @return mixed
*/
public function validate($message);
}
<?php
namespace OneThirtyOne\Sns;
use Aws\Sns\MessageValidator;
use OneThirtyOne\Sns\Concerns\SnsValidatorInterface;
/**
* Class Validator.
*/
class Validator implements SnsValidatorInterface
{
/**
* @var \Aws\Sns\MessageValidator
*/
protected $validator;
/**
* Validator constructor.
*/
public function __construct()
{
$this->validator = new MessageValidator();
}
/**
* {@inheritdoc}
*/
public function validate($message)
{
$this->validator->validate($message);
}
}
Then in my SnsServiceProvider I bound those interfaces to their classes
/**
* Register the Service Provider.
*
* @return void
*/
public function register()
{
$this->app->bind(SnsMessageInterface::class, Message::class);
$this->app->bind(SnsValidatorInterface::class, Validator::class);
}
Now in my SnsController I type hinted to those interfaces
<?php
namespace OneThirtyOne\Sns\Controllers;
use Aws\Sns\Exception\InvalidSnsMessageException;
use Illuminate\Support\Facades\Http;
use OneThirtyOne\Sns\Concerns\SnsMessageInterface;
use OneThirtyOne\Sns\Concerns\SnsValidatorInterface;
use OneThirtyOne\Sns\Events\SnsEvent;
use OneThirtyOne\Sns\Events\SnsSubscriptionConfirmation;
/**
* Class SnsController.
*/
class SnsController
{
/**
* @var \OneThirtyOne\Sns\Concerns\SnsMessageInterface
*/
protected $message;
/**
* @var \OneThirtyOne\Sns\Concerns\SnsValidatorInterface
*/
protected $validator;
/**
* @var array
*/
protected $confirmation = [
'SubscriptionConfirmation',
];
/**
* @var array
*/
protected $notification = [
'Notification',
];
/**
* SnsController constructor.
*
* @param \OneThirtyOne\Sns\Concerns\SnsMessageInterface $message
* @param \OneThirtyOne\Sns\Concerns\SnsValidatorInterface $validator
*/
public function __construct(SnsMessageInterface $message, SnsValidatorInterface $validator)
{
$this->message = $message;
$this->validator = $validator;
}
/**
* Handle the HTTP Request from SNS Service.
*
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
*/
public function handle()
{
try {
$this->validator->validate($this->message->get());
} catch (InvalidSnsMessageException $e) {
return response('SNS Message Validation Error: '.$e->getMessage(), 404);
}
if (in_array($this->message->Type, $this->confirmation)) {
$response = Http::get($this->message->SubscribeURL);
if ($response->ok()) {
SnsSubscriptionConfirmation::dispatch($this->message);
}
return response('OK', 200);
}
if (in_array($this->message->Type, $this->notification)) {
SnsEvent::dispatch($this->message);
}
return response('OK', 200);
}
}
From this point I seem to have successfully decoupled my app from the aws-sdk and now I can mock my interfaces in my tets
Hope this helps someone down the road.