I can't get this obvious test to pass.
Foo gets a Bar in its constructor and when calling Foo::m(), Bar::bar() gets called.
use PHPUnit\Framework\TestCase;
class Bar {
public function bar() {
echo "BAR";
}
}
class Foo {
protected $bar;
public function __construct($bar) {
$this->bar= $bar;
}
public function m() {
$this->bar->bar();
}
}
class FooTest extends TestCase {
public function testM() {
$bar = $this->prophesize(Bar::class);
$bar->bar()->shouldBeCalled();
$foo = new Foo($bar);
$foo->m();
}
}
Prophecy fails to register the call to Bar::bar() somehow...
Some predictions failed:
Double\Bar\P1:
No calls have been made that match:
Double\Bar\P1->bar()
but expected at least one.
Your $bar variable contains an instance of ObjectProphecy, which is unrelated to the Bar class. Call $bar->reveal() to get a test double which is an extension of Bar:
public function testM()
{
$bar = $this->prophesize(Bar::class);
$bar->bar()->shouldBeCalled();
$foo = new Foo($bar->reveal());
$foo->m();
}
Related
I am writing a test for a service class which is dependant on another service class.
Foo.php
class Foo {
public function __construct(Bar $bar)
{
$this->bar = $bar;
}
public function fooMethod()
{
$getSomeArrayOrNull = null;
$this->bar->barMethod($getSomeArrayOrNull);
}
}
Bar.php
class Bar {
public function barMethod(array $array)
{
return null;
}
}
Test.php
class Test extends TestCase {
public function testIt()
{
$bar = Mockery::mock(Bar::class);
$bar->shouldReceive('barMethod')->withAnyArgs()->andReturn(true);
$foo = new Foo();
// this throws an error because invalid argument type in Bar method
$foo->fooMethod();
}
}
Can i somehow tell mockery to ingore type checking in the $bar->barMethod()?
I am writing the unit test and i would like to have this part of the code totaly mocked.
Is this a bad code smell, should i just mock the $getSomeArrayOrNull property also? (witch means alyways an array)
I didn't get why the first output of the code prints "Bar::testPrivate" as we are calling the test method of the parent class using sub class's instance.So, when calling the first line of code inside the test function which is "$this->testPrivate();" should call testPrivate method of the sub class hence printing "Foo::testPrivate" and not "Bar::testPrivate".
<pre>
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
</pre>
Your class Foo doesn't have a test() method. You can call $myFoo->test() because the method test() is inherited from class Bar. You'll have to override the method test() within class Foo just as you did with methods testPrivate() and testPublic().
You are correct that it is calling the method of the base class, but in this case Bar is your base class. Check out the example here.
If you are looking to inherit all the functions from your base (parent) class then you should explicitly call it's constructor in the child class. Otherwise you will need to override those methods. Also, when using the actual instance (i.e. you created an object) functions declared private are only available to that class. Use protected for classes that will inherit that function. e.g.:
class Foo {
public function __construct() {
echo "Foo constructed...\n";
$this->fooOnly();
}
private function fooOnly() {
echo "Called 'fooOnly()'\n"; //Only available to class Foo
}
protected function useThisFoo() {
echo "Called 'useThisFoo()'\n"; //Available to Foo and anything that extends it.
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct(); //Now Bar has everything from Foo
}
public function testFooBar() {
//$this->fooOnly(); //Fail - private function
$this->useThisFoo(); //Will work - protected function is available to Foo and Bar
}
}
$bar = new Bar();
$bar->testFooBar(); //Works - public function will internally call protected function.
//$bar->fooOnly(); //Fail - private function can't be accessed in global space
//$bar->useThisFoo(); //Fail again - protected function can't be access in global space
I am trying to access the results of a function that is public inside another class, but I'm not entirely sure how to do this. The class i'm trying to access require parameters, so the class_name::function() method is not working. I'm still new to working with classes, and trying to learn it.
Class one:
class foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
echo $this->var1;
}
}
Class 2
class bar {
public function secondFunc() {
var_dump(**RESULT FROM foo->myFunc HERE);
}
}
These two classes are a basic example of what i'm actually doing, but from this you should get the general idea of my question.
For the correct result to display, the first class needs the params passed to it otherwise the function fails.
I tried using foo::bar(), but this doesn't pass any params to the first class, and it therefor fails.
So, how do I access myFunc from foo inside secondFunc from bar?
You have to pass an instance of foo to bar:
class Foo {
private $var1;
function __construct($param) {
$this->var1 = $param
}
public function myFunc() {
return $this->var1;
}
}
class Bar {
private $foo;
function __construct(Foo $foo) {
$this->foo = $foo
}
public function secondFunc() {
var_dump($this->foo->myFunc());
}
}
$bar = new Bar(new Foo('something'));
$bar->secondFunc();
Is that what you want?
Your example isn't very practical but here is the basic idea
public function secondFunc($dependency) {
var_dump($dependency->myFunc());
}
or...
public function secondfunc() {
$foo = new foo();
var_dump($foo->myFunc();
}
What about
class bar {
public function secondFunc() {
$foo = new foo($param);
var_dump($foo->myFunc());
}
}
Or do you need something in one line?
I have the follow (sample) code:
class Foo {
public function __construct() {
$this->bar = new Bar();
$this->baz = new Bazr();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
$baz = $this->baz->alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo('Hello!');
}
}
new Foo();
Which will generate an Fatal error: Maximum function nesting level of '100' reached, aborting!. What I want is, exactly this, ofcourse with different code and no errors.
What I want is one way to know when my instance is already created and not allow more instances of same object, avoiding circular reference.
Learned about Singletom, but, nothing worked. Have any idea?
The constructor of Foo calls the constructor of Bar which calls the constructor of Foo which calls the constructor of Bar... you get the idea. After 100 times it tells you it's dizzy. Don't create a circular reference like that.
I do not quite understand why you need all this? If only because to get methods of Bar/Baz in class Foo, then you can use:
class Foo {
public function __construct() {
Bar::init();
}
}
class Bar extends Foo {
public function __construct() {
parent::__construct();
}
public function init() {
Baz::alert();
}
}
class Baz extends Foo {
public function __construct() {
parent::__construct();
}
public function alert() {
echo 'Hello!';
}
}
new Foo();
Implement dependence Injection is the solution:
class Foo {
public function __construct() {
$this->bar = new Bar(new Baz());
}
}
class Bar {
public function __construct($baz = null) {
$this->baz = $baz;
$this->baz->alert();
}
}
class Baz {
public function __construct() {
}
public function alert() {
echo('Hello!');
}
}
new Foo();
I want to check is a function exists in a library that I am creating, which is static. I've seen function and method_exists, but haven't found a way that allows me to call them in a relative context. Here is a better example:
class myClass{
function test1()
{
if(method_exists("myClass", "test1"))
{
echo "Hi";
}
}
function test2()
{
if(method_exists($this, "test2"))
{
echo "Hi";
}
}
function test3()
{
if(method_exists(self, "test3"))
{
echo "Hi";
}
}
}
// Echos Hi
myClass::test1();
// Trys to use 'self' as a string instead of a constant
myClass::test3();
// Echos Hi
$obj = new myClass;
$obj->test2();
I need to be able to make test 3 echo Hi if the function exists, without needing to take it out of static context. Given the keyword for accessing the class should be 'self', as $this is for assigned classes.
static::class is available since PHP 5.5, and will return the "Late Static Binding" class name:
class myClass {
public static function test()
{
echo static::class.'::test()';
}
}
class subClass extends myClass {}
subClass::test() // should print "subClass::test()"
get_called_class() does the same, and was introduced in PHP 5.3
class myClass {
public static function test()
{
echo get_called_class().'::test()';
}
}
class subClass extends myClass {}
subClass::test() // should print "subClass::test()"
The get_class() function, which as of php 5.0.0 does not require any parameters if called within a class will return the name of the class in which the function was declared (e.g., the parent class):
class myClass {
public static function test()
{
echo get_class().'::test()';
}
}
class subClass extends myClass {}
subClass::test() // prints "myClass::test()"
The __CLASS__ magic constant does the same [link].
class myClass {
public static function test()
{
echo __CLASS__.'::test()';
}
}
class subClass extends myClass {}
subClass::test() // prints "myClass::test()"
Update:
Ahh, apologies. I was temporarily blind :) You'll want to use the magic constant __CLASS__
e.g.
if (method_exists(__CLASS__, "test3")) { echo "Hi"; }
for all situations… the best usage would be…
if method_exist(…) && is_callable(…)
For testing example:
class Foo {
public function PublicMethod() {}
private function PrivateMethod() {}
public static function PublicStaticMethod() {}
private static function PrivateStaticMethod() {}
}
$foo = new Foo();
$callbacks = array(
array($foo, 'PublicMethod'),
array($foo, 'PrivateMethod'),
array($foo, 'PublicStaticMethod'),
array($foo, 'PrivateStaticMethod'),
array('Foo', 'PublicMethod'),
array('Foo', 'PrivateMethod'),
array('Foo', 'PublicStaticMethod'),
array('Foo', 'PrivateStaticMethod'),
);
foreach ($callbacks as $callback) {
var_dump($callback);
var_dump(method_exists($callback[0], $callback[1])); // 0: object / class name, 1: method name
var_dump(is_callable($callback));
echo str_repeat('-', 40), "n";
}
Source here