Is it possible to return mock from mocked method? - phpunit

I have the Factory
class DocumentManagerFactory
{
....
public function createDocumentManager(): DocumentManager
{
return DocumentManager::create($this->client, $this->configuration);
}
}
And I want to mock the DocumentManager which returns by createDocumentManager
$dmStub = $this->createMock(DocumentManager::class)
->method('refresh')
->willReturnArgument(1);
$dmFactoryStub = $this->createMock(DocumentManagerFactory::class)
->method('createDocumentManager')
->willReturn($dm);
I get the following Error:
Method createDocumentManager may not return value of type PHPUnit\Framework\MockObject\Builder\InvocationMocker, its return declaration is ": Doctrine\ODM\MongoDB\DocumentManager"
Is it possible?

It's because you are chaining your invocations to the mock and then assigning those to the variable. If you split them up it should work without issue.
$dmStub = $this->createMock(DocumentManager::class);
$dmStub->method('refresh')
->willReturnArgument(1);
$dmFactoryStub = $this->createMock(DocumentManagerFactory::class);
$dmFactoryStub->method('createDocumentManager')
->willReturn($dm);
In this situation the variable actually holds the object instead of the invocation.

Related

phpunit replace the method return

Here is my code. How can I modify the function's return result.
class Replace {
public function add($a){
// how can I replace $this->double($anyNum) return value
return $a + $this->double($a);
}
public function double($a){
return $a + $a;
}
}
class ReplaceTest extends PHPUnit_Framework_TestCase {
public function testadd(){
$replace = $this->getMock('Replace');
// I want to control the method's return,
//no matter what num passed to it from function add
$replace->expects($this->any())->method('double')->will($this->returnValue(15));
// this return null
$data = $replace->add(6);
// this is the expected result I want,
// and when I set the returnValue(21),I hope the expected result is 27
$this->assertEquals(21, $data);
}
}
How can I modify my code, thank you very very much.
If specified, the second parameter of getMock() tells phpunit which methods to replace. Thus, in your case:
$replace = $this->getMock('Replace',array('add'))
Although in the example you gave, I'd recommend not mocking the Replace class, adding a test for the double() method will suffice, as if the double() test passes, you can rely on that method's result.

Symfony2 set class variable with init or construct methods

Have recently been using Symfony2 after using ZF for some time.
I am having problems trying to do something relatively simple, I think.
The following code is within a controller:
private $current_setid = "";
public function __construct() {
$current_set = $this->getCurrentSet();
if ($current_set == "") {
return $this->redirect($this->generateUrl('selectset'));
}
$this->current_setid = $current_set;
}
public function getCurrentSet() {
$session = $this->get("session");
$set = $session->get('set');
return $set;
}
public function setCurrentSet($setid) {
$session = $this->get("session");
$session->set('set', "$setid");
}
If I use __construct() I get errors like:
Fatal error: Call to a member function get() on a non-object in
I have tried using __init() and init() both of which do not seem to get called.
Can anyone point me in the right direction? Is there a simple way to do this or do I have to look into event listeners?
Have you tried getting your session like they do in official documentation?
$session = $this->getRequest()->getSession();
$foo = $session->get('foo');
Basically get fetch dependencies from container and container in the Controller is injected using setter dependency injection. You just not have container in the time of __construct yet.
Just ended up opting for placing a check in every method in the class. Seems silly to have to do that but I find I often have to do that in Symfony2 with the lack of init, postDispatch type methods like ZF has.
Even trying to remove the check to another method was counter productive as I still had to check the return from that method as $this->redirect does not seem to work unless it is within an Action method. For example:
public function isSetSet() {
$current_set = $this->getCurrentSet();
if ($current_set == "") {
$url = $this->generateUrl('selectset');
return $this->redirect($url);
}
return TRUE;
}
public function someAction() {
$check = $this->isSetSet();
if($check != TRUE){
return $check;
}
...
}
So each method needs that 4 line check but the whole check can be done in 4 lines anyway so no need for that extra method:
public function anotherAction() {
$current_setid = $this->getCurrentSet();
if ($current_setid == "") {
return $this->redirect($this->generateUrl('selectset'));
}
...
}

Pass property from controller to Model

I am trying to pass a variable from a method in my Controller to a method in a Model. Since the method in the Model takes one argument (which was designed earlier), I cannot pass my variable as an argument to the method in the Model. And also, the method in this Model is called by other controllers too, so if I change the argument, I have to change all the controllers too, which would be a tedious task.
What I have been trying so far is- I created one MyVariableClass and declared a property. Then I instantiated that class and set the property string to the variable that I wanted to pass. Now, in my Model's method, I instantiated the same MyVariableClass again, but when I did that, the value of the variable was set to null. The code I have right now is -
public ActionResult ItemInformation( string id)
{
//Pass a string to MyVariable
MyVariableVClass params = new MyVariableClass();
params.myVariable = "abc";
//This is what My Model is taking as an argument(id), and I don't want to
//pass mYvariable along with that argument because it will break other controllers
// too which calls this method
var itemInformation = _repository.GetItemInformation(id);
return View(itemInformation);
}
and MyVariableClass
public class MyVariableClass
{
public string myVariable { get; set; }
}
and the method in My Model
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass webType = new MyVariableClass();
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params =="this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
Anybody has solution to this? Thanks in Advance!
Any reason why subclassing your model and overriding the GetItemInformation method wouldn't work? Or, even easier, why not just overload the GetItemInformation method with one that takes two strings? Your other controllers can still use the one that only takes a single string.
public IList<Items> GetItemInformation(string itemId, MyVariableClass webType)
{
var _params = webType.myVariable;
//Check this variable and perform database query
if (_params == "this")
{
var query = myFirstQuery;
}
else
{
var query = mySecondQuery;
}
//return ....
}
public IList<Items> GetItemInformation(string itemId)
{
MyVariableClass fauxType = new MyVariableClass();
fauxType.myVariable = "not this";
return GetItemInformation(itemId, fauxType);
}
Try using session variable.

flex: referencing class variables

I have a bunch of variables in a class. There are situations when I want to set then to null/ "temp" etc as per a well defined logic. The challenge is to list out the variables at multiple places- tedious and error-prone.
classname.speed=NaN
classname.speedtype="not_set"
classname.distance=NaN
classname.distancetype="not_set"
Ideally, would prefer a way to refer to these variables programatically and set something like
"for all class variables- if variable ends in type, set as "not_set"; for other variables set as NaN
How can I achieve this? Any pointers will help
The simplest approach would be just write function to clear them all.
If you want something more automatic, it will requre efforts - look at introspection api. Basically, you call describeType on your class and it returns XML description. All variables will be listed there, along with other info. Then you can parse returned XML and set all variables to needed value, accessing them dynamically with square bracket syntax:
var myClass:MyClass = new MyClass();
myClass["varName"] = "new value";
It can be achieved through Inheritance i.e. implementing interface or extending class
which contains common fields
public class MyClass
{
public a:String = null;
public b:String = null;
public function MyClass()
{
}
}
which contains common var and Child Class could be
public class MyClassChild extends MyClass
{
public var c:String = null;
public function MyClassChild()
{
super();
this.a ="";
this.b ="";
}
}
and you can cast or use for each loop to set values
var temp:MyClassChild = new MyClassChild ();
MyClass(temp).a = "Hello World";
Hopes that helps

Passing values between functions

Hi All is there any way to locally define a variable in a function and then pass it to the oher function. I mean to say is it possible the pass a local value from one function to other function.
Somebody Please suggest me the solution.
Thanks in advance
Or it's that simple or you meant something else:
private function function1():void
{
var localVariable:String = "this is local variable of function1()";
function2(localVariable);
}
private function function2(string:String):void
{
trace(string);
}
function1();
or use global variable as temporary storage:
private var globalVariable:String = "";
private function function1():void
{
var localVariable:String = "this is local variable of function1()";
globalVariable = localVariable;
}
private function function2():void
{
trace(globalVariable);
}
function1();
function2();
zdmytriv is right.
Although, you can also make default variables, like so:
(Modifying zdmytriv's code)
private function function1():void
{
var localVariable:String = "this is local variable of function1()";
function2(localVariable);
function2(); //You don't have to enter a default argument
}
private function function2(string:String = "something else"):void
{
trace(string);
}
This would trace:
this is local variable of function1()
something else
A little off topic, but good to know.
Primitives in Flex are passed by value, where complex objects are passed by reference. You can use this to pass objects around without scoping a variable outside the functions themselves. For instance:
private function function1():void {
{
var localVar:Object = {value:"test"};
trace(localVar.value);
function2(localVar);
trace(localVar.value);
}
private function function2(obj:Object):void
{
obj.value = "new value";
}
This would trace:
test
new value
Which reflects the fact that function2 receives the parameter "obj" by reference, as a pointer to the original "localVar" object. When it sets the .value field, that change is reflected in function1.
I just thought I'd point that out.

Resources