PHPUnit Mocking Wrapper Instances - phpunit

I have this wrapper:
class APIWrapper {
protected static $clientClass = \Hardcoded_API; // from a library
protected $client;
public function __construct() {
$this->client = new self::$clientClass(array_merge(self::$config, $config));
}
/**
* Does something.
*
* #throws SomeException
*/
public function act() {
$this->client->doSomething();
}
public static function setClientClass($clientClass) {
self::$clientClass = $clientClass;
}
}
Now let's say I am testing functions that make use of this wrapper:
class UnrelatedFunction {
public function callAPI() {
$wrapper = new APIWrapper();
try {
$wrapper->act();
} catch (SomeException $e) {
// ... do other things
}
}
}
class UnrelatedFunctionsTest extends PHPUnit_Framework_TestCase {
public function testUnrelatedFunctionException() {
$unrelatedFunction = new UnrelatedFunction();
$this->setExpectedException('SomeException');
// this call triggers the APIWrapper
$unrelatedFunction->callAPI();
// Some assertions here...
}
}
I need to be able to verify that UnrelatedFunction::callAPI() did its job recovering from the exception. In this case, how can I mock a \Hardcoded_API class, make it throw a SomeException when act() is called, and pass it onto APIWrapper::setClientClass() so that I can test the behaviour?

Related

How to fix Avoid unused parameters PHPMD of protected method in parent class

I have two class :
class EntityVoter
{
protected function canPutToBlockChain($entity, $viewer)
{
return false;
}
}
class VerificationVoter extends EntityVoter
{
public function canPutToBlockChain($entity, $viewer)
{
return $this->canShare($entity, $viewer);
}
}
PHPMD scan EntityVoter class and throw: Avoid unused parameters such as '$entity', '$viewer'.
My solution is creating a interface:
interface EntityVoterInterface
{
function canPutToBlockChain($entity, $viewer);
}
and then add #inhericDoc annotation:
class EntityVoter implements EntityVoterInterface
{
/**
* #inheritDoc
*/
protected function canPutToBlockChain($entity, $viewer)
{
return false;
}
}
Is there any better solution ?

Expand base-class with more methods from other bundle (by di-service?)

I have a 2 Bundles.
Bundle 1:
class EntityOne {
private $_foo;
public function setFoo($foo)
{
$this->_foo = $foo;
return $this;
}
public function getFoo()
{
return $this->_foo;
}
}
My Service (service.yml)
service:
MyFooProject\Entity:
class: MyFooProject\Entity\EntityOne
Bundle 2:
class EntityTwo extends \MyFooProject\Entity\EntityOne {
private $_bar;
public function setBar($bar)
{
$this->_bar = $bar;
return $this;
}
public function getBar()
{
return $this->_bar;
}
}
My Service (service.yml)
service:
MyBarProject\Entity\EntityTwo
parent: MyFooProject\Entity\EntityOne
Now I want call Method setBar() in Bundle 1 but Symfony didn't find Method setBar() from Bundle 2
function test()
{
$oEntity = $this->get(MyFooProject\Entity\EntityOne::class);
$oEntity->setFoo("foo");
$oEntity->setBar("bar"),
}
How can I solve the problem?

Symfony2 Service with an unique instance

Please i need some help:
I have the following services:
SERVICE CONFIGURATION IN services.yml
services:
xpad.producto_repository:
class: Xpad\ProductoBundle\Entity\ProductRepository
factory_service: doctrine.orm.clientes_entity_manager
factory_method: getRepository
arguments:
- Xpad\ProductoBundle\Entity\Product
backend_cliente.producto_filters:
class: Xpad\BackendClienteBundle\Filters\ProductFilters
calls:
- [setRepository, ["#xpad.producto_repository="]]
scope: container
AND THE CLASS FOR backend_cliente.producto_filters IS:
namespace Xpad\BackendClienteBundle\Filters;
use Xpad\ProductoBundle\Entity\ProductRepository;
class ProductFilters
{
private $_queryBuilder;
public function getQueryBuilder()
{
return $this->_queryBuilder;
}
public function setQueryBuilder($queryBuilder)
{
$this->_queryBuilder = $queryBuilder;
}
public function setRepository(ProductRepository $productRepository = null)
{
if($this->_queryBuilder == null)
{
$this->_queryBuilder = $productRepository->createQueryBuilder('p');
}
}
}
AND I HAVE THE FOLLOWING ACTION IN ONE OF MY CONTROLLERS:
class ProductController extends Controller
{
............
public function indexAction(Request $request)
{
//SOME CODE
$service_filter = $this->container->get('backend_cliente.producto_filters');
$queryBuilder = $service_filter->getQueryBuilder();
//SOME OTHER CODE
}
MY PROBLEM IS: ANYTIME THAT THE indexAction is execute I GOT A NEW INSTANCE OF backend_cliente.producto_filters SERVICE AND I DON'T KNOW WHY. I NEED AND UNIQUE INSTANCE AS A SINGLETON BECAUSE A HAVE THE $_queryBuilder ATRIBUTTE AND I NEED TO GET THE VALUE OF IT JUST MODIFY ITS VALUE WHEN IS NEEDED;
PLEASE HELP I DON KNOW WHAT I'M DOING WRONG.
Do you have to use the class as a service?
Why don't you use a Singleton, without using a service? Like this:
namespace Xpad\BackendClienteBundle\Filters;
use Xpad\ProductoBundle\Entity\ProductRepository;
class ProductFilters {
private $_queryBuilder;
private static $reference = null;
public function getInstance(){
if (self::$reference === null)
self::$reference = new ProductFilters();
return self::$reference;
}
private function __construct(){}
public function getQueryBuilder()
{
return $this->_queryBuilder;
}
public function setQueryBuilder($queryBuilder)
{
$this->_queryBuilder = $queryBuilder;
}
public function setRepository(ProductRepository $productRepository = null)
{
if($this->_queryBuilder == null)
{
$this->_queryBuilder = $productRepository->createQueryBuilder('p');
}
}
}
And call it with:
...
$filter = ProductFilters::getInstance();
...

Finding out where TypeErrors are thrown

I am having a problem that is driving me nuts.
Recently I configured my BlazeDS to use Array instead of ArrayCollection for performance reasons. Additionally I adjusted my templates to generate Array properties.
Everything wen't fine. All except one function that causes TypeError: Error #1034. These are being thrown before the result callback is called. It claims to have problems casting an ArrayCollection to Array. I removed the generated types to make Flex use Objects instead, but these did not contain any ArrayCollections. My question now is: How can I get the stack-traces of errors thrown in event-handlers?
I allready added handlers for unhandledExceptions in all of my modules and they are called if errors occur in code triggered from user-interaction, but they don't seem to be able to catch stuff thrown by event-handlers.
How can I track these Errors?
Chris
PS: The classes are:
package de.upw.ps.ucg.model.ucg.scheduler {
[Bindable]
[RemoteClass(alias="de.upw.ps.ucg.model.ucg.scheduler.Task")]
public class Task extends TaskBase {
}
}
And:
package de.upw.ps.ucg.model.ucg.scheduler {
import de.upw.ps.ucg.model.oval.common.OvalVersionedIdentifier;
import flash.utils.IExternalizable;
[Bindable]
public class TaskBase {
public function TaskBase() {}
private var _aborted:Boolean;
private var _characteristicsId:String;
private var _currentExecutorPhase:JobExecutorPhase;
private var _definitionSetName:String;
private var _definitionSetVid:OvalVersionedIdentifier;
private var _endTime:Date;
private var _enqueueTime:Date;
private var _environmentId:String;
private var _environmentName:String;
private var _messages:Array;
private var _numberOfDefinitions:int;
private var _processedNumberOfTests:int;
private var _resultsId:String;
private var _schedulerJob:SchedulerJob;
private var _startTime:Date;
private var _statusMessage:String;
private var _taskId:String;
private var _totalNumberOfTests:int;
public function set aborted(value:Boolean):void {
_aborted = value;
}
public function get aborted():Boolean {
return _aborted;
}
public function set characteristicsId(value:String):void {
_characteristicsId = value;
}
public function get characteristicsId():String {
return _characteristicsId;
}
public function set currentExecutorPhase(value:JobExecutorPhase):void {
_currentExecutorPhase = value;
}
public function get currentExecutorPhase():JobExecutorPhase {
return _currentExecutorPhase;
}
public function set definitionSetName(value:String):void {
_definitionSetName = value;
}
public function get definitionSetName():String {
return _definitionSetName;
}
public function set definitionSetVid(value:OvalVersionedIdentifier):void {
_definitionSetVid = value;
}
public function get definitionSetVid():OvalVersionedIdentifier {
return _definitionSetVid;
}
public function set endTime(value:Date):void {
_endTime = value;
}
public function get endTime():Date {
return _endTime;
}
public function set enqueueTime(value:Date):void {
_enqueueTime = value;
}
public function get enqueueTime():Date {
return _enqueueTime;
}
public function set environmentId(value:String):void {
_environmentId = value;
}
public function get environmentId():String {
return _environmentId;
}
public function set environmentName(value:String):void {
_environmentName = value;
}
public function get environmentName():String {
return _environmentName;
}
public function set messages(value:Array):void {
_messages = value;
}
public function get messages():Array {
return _messages;
}
public function set numberOfDefinitions(value:int):void {
_numberOfDefinitions = value;
}
public function get numberOfDefinitions():int {
return _numberOfDefinitions;
}
public function set processedNumberOfTests(value:int):void {
_processedNumberOfTests = value;
}
public function get processedNumberOfTests():int {
return _processedNumberOfTests;
}
public function set resultsId(value:String):void {
_resultsId = value;
}
public function get resultsId():String {
return _resultsId;
}
public function set schedulerJob(value:SchedulerJob):void {
_schedulerJob = value;
}
public function get schedulerJob():SchedulerJob {
return _schedulerJob;
}
public function set startTime(value:Date):void {
_startTime = value;
}
public function get startTime():Date {
return _startTime;
}
public function set statusMessage(value:String):void {
_statusMessage = value;
}
public function get statusMessage():String {
return _statusMessage;
}
public function set taskId(value:String):void {
_taskId = value;
}
public function get taskId():String {
return _taskId;
}
public function set totalNumberOfTests(value:int):void {
_totalNumberOfTests = value;
}
public function get totalNumberOfTests():int {
return _totalNumberOfTests;
}
}
}
Both classes are generated by my maven build from a corresponding Java Class and the Types do fit together nicely.
Do you have access to the socket class that's reading in all these messages? Trace out the buffer before the deserialisation and you should at least be able to find the class that's giving you hassle.
Failing that, trace out the object after deserialisation and it should be the very first one after the error is thrown.
This is something you'll have to debug on your own, but I have a gut feeling that the problem is because the data being sent by your java DTO is not the same as your AS3 class, even though that you have the RemoteClass metadata saying that it is.
Are you missing a property? or have a property mismatch? That is the most likely cause of your error. I suggest you debug the java side as much as you can and use something like firebug to see the request/response of the server.

can not access MovieClip properties in flashDevelop

I know there is something I am doing wrong. In my controls I have keydown events that control my hero. As of right now, I am trying to rotate my hero but he refuses to turn . Below is my Hero Class, my control class, and gameobject class. pretty much all the classes associate with the controls class.
package com.Objects
{
import com.Objects.GameObject;
/**
* ...
* #author Anthony Gordon
*/
[Embed(source='../../../bin/Assets.swf', symbol='OuterRim')]
public class Hero extends GameObject
{
public function Hero()
{
}
}
}
Here is my Controls class. This is the class where I am trying to rotate my hero but he doesnt. The keydown event does work cause I trace it.
package com.Objects
{
import com.Objects.Hero;
import flash.events.*;
import flash.display.MovieClip;
/**
* ...
* #author Anthony Gordon
*/
public class Controls extends GameObject
{
private var aKeyPress:Array;
public var ship:Hero;
public function Controls(ship:Hero)
{
this.ship = ship;
IsDisplay = false;
aKeyPress = new Array();
engine.sr.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
engine.sr.addEventListener(KeyboardEvent.KEY_UP,keyUpListener);
}
private function keyDownListener(e:KeyboardEvent):void {
//trace("down e.keyCode=" + e.keyCode);
aKeyPress[e.keyCode] = true;
trace(e.keyCode);
}
private function keyUpListener(e:KeyboardEvent):void {
//trace("up e.keyCode=" + e.keyCode);
aKeyPress[e.keyCode]=false;
}
override public function UpdateObject():void
{
Update();
}
private function Update():void
{
if (aKeyPress[37])//Key press left
ship.rotation += 3,trace(ship.rotation ); ///DOESNT ROtate
}//End Controls
}
}
Here is GameObject Class
package com.Objects
{
import com.Objects.Engine;
import com.Objects.IGameObject;
import flash.display.MovieClip;
/**
* ...
* #author Anthony Gordon
*/
public class GameObject extends MovieClip implements IGameObject
{
private var isdisplay:Boolean = true;
private var garbage:Boolean;
public static var engine:Engine;
public var layer:Number = 0;
public function GameObject()
{
}
public function UpdateObject():void
{
}
public function GarbageCollection():void
{
}
public function set Garbage(garb:Boolean):void
{
garbage = garb;
}
public function get Garbage():Boolean
{
return garbage
}
public function get IsDisplay():Boolean
{
return isdisplay;
}
public function set IsDisplay(display:Boolean):void
{
isdisplay = display;
}
public function set Layer(l:Number):void
{
layer = l;
}
public function get Layer():Number
{
return layer
}
}
}
Looks like your keyUpListener and keyDownListener methods aren't calling the UpdateObject function.
Try listening for your KeyboardEvent on stage instead of engine.sr (not sure what that is)
If you put them on anything other than the stage you will need to click that specific thing first to give it focus for the events to work.
Also, the line:
ship.rotation += 3,trace(ship.rotation );
in your Control class looks a bit broken.

Resources