I am using Netbeans, and I love it.
However, my scenario is, when I want to use object B in object A, I can not use the autocomplete feature on $this->B->
(Yes, I know, the below code has syntax error, the question is not about syntax).
So, for example:
require_once('Legion.class.php');
class MyClass {
private $Legion;
public function __construct() {
$this->Legion = Legion::getInstance();
}
public function showResult() {
$this->Legion-> //Not works here
$Legion = $this->Legion;
$Legion-> //Works
}
}
When I typed $this->Legion-> I've got some basic functions, keywords, like do, echo, while etc...
But if I am create a new variable for this object B, then I've get back all of it accessable methods, and properties.
After this I've also tried to use vdoc without success:
/* #var $Legion Legion */
/* #var $this->Legion Legion */
Is somebody faced with this issue? Is there a solution for that?
Try to use correct PHP Doc
/**
* My Legion
* #var Legion
*/
private $Legion;
-> http://manual.phpdoc.org/HTMLSmartyConverter/PHP/phpDocumentor/tutorial_tags.var.pkg.html
Related
What is the correct way of setting a type for mocked objects?
Example code:
/**
* #dataProvider getTestDataProvider
* #throws Exception
*/
public function testExampleData(
Request $request,
Response $expected,
SomeClass $someClassMock
): void {
$result = $someClassMock->getData($request);
$this->assertEquals($expected, $result);
}
In this example the type of $someClassMock is class SomeClass. Also there is a type called MockObject which is also working properly, but it messes up the autocompletion of functions inside that class.
Which types should I use on these mocked objects? Real object class or MockObject?
What I do to make sure the auto completion works for the mocked class as well as the MockObject, is tell php that it can be either class. This adds the auto complete for both and also makes it quite understandable for anyone reading the code that it is a mock and what object it is mocking.
In your case it would look like this:
/**
* #dataProvider getTestDataProvider
* #throws Exception
*/
public function testExampleData(
Request $request,
Response $expected,
SomeClass|MockObject $someClassMock // <-- Change made here
): void {
$result = $someClassMock->getData($request);
$this->assertEquals($expected, $result);
}
You will still be passing in the MockObject, but your IDE will not complain about any unknown functions.
EDIT: To make it work with PHP versions before 8, I would suggest something like this (minimal example):
class ExampleTest extends TestCase
{
private someClass | MockObject $someClassMock;
public function setUp(): void
{
$this->someClassMock = $this->createMock(SomeClass::Class);
}
public function testMe()
{
$this->someClassMock->expects($this->once())->method('getData')->willReturn('someStuff');
}
}
In this scenario the variable $someClassMock is declared as both types and you can use it throughout your test with autocompletion for both of them. This should also work with your data provider although you might have to rewrite it slightly. I didn't include it in my example to keep it simple.
Given the following code structure is there a way that I can get the return type of FooFactory->createService method with PHP 5.6? I've tried ReflectionClass and ReflectionMethod classes but couldn't find a way.Thanks in advance.
class FooFactory implements FactoryInterface {
public function createService(/*args*/)
{
$foo = new Foo();
// ...
//inject dependencies
// ...
return $foo;
}
}
class Foo {
/*...methods...*/
}
Edit: I need to get the class name without creating an instance of the FooFactory.
Using PHP5 this is not possible.
You could (and this is more of a workaround than a solution) type hint your variable on declaration. This would expose the methods etc belonging to created service to your IDE.
Example:
/* #var \MyFooService $myFooService */
$myFooService = FooFactory->createServixce('MyFooService');
Note it is the #var declaration that will inform your editor of the variable type.
Syntax being:
/* #var [CLASS_NAME] [VARIABLE] */
UPDATE:
Just seen you dont want to create an instance of FooFactory.
By default arn't factory methods static?
So:
$fooFactory = new FooFactory();
$fooService = FooFactory->getService('FooService');
Becomes:
$fooService = FooFactory::getService('FooService');
I have a class which includes a file in a method like below:
In class.php file:
class A {
const CONST1 = 5;
/** #var int $a */
var $a = 5;
public function call()
{
include( 'b.php' );
}
public function do_some_magic()
{
// magic stuff...
}
public static function static_func()
{
// some code...
}
}
file b.php:
<?php
/** #var A $this */
/** #var A self */ // This doesn't work
$this->do_some_magic();
echo '['.$this->a.']';
self::static_func();
echo '['.self::CONST1.']';
I use PhpStorm as IDE and in b.php file if I want to go to definition of do_some_magic() or definition of a variable it will correctly go to corresponding method or variable definition in class.php file, but if I want to go to definition of constant CONST1 or to definition of static method static_func() it says "Cannot find definition to go to", so I think /** #var A self */ is not a valid notation in included file.
My question is: Is there any way in PhpDoc to tell IDE of what type self is in included file?
I searched for an answer, but as it seems at the moment only way to have auto-complete in an included file you will have to make static calls using class name. Of course, this would fail if you include the file in different classes and you want self to mean that specific class where the file was included.
So b.php would look like:
<?php
/** #var A $this */
/** #var A self */ // This doesn't work
$this->do_some_magic();
echo '['.$this->a.']';
A::static_func();
echo '['.A::CONST1.']';
If however you find a better answer please let me know.
Regards,
Andy
class myclass {
private $myemail = '';
private $myPrefix = '';
/**
* #return string
*/
public function getmyPrefix()
{
return $this->myPrefix;
}
/**
* #return string
*/
public function getmyEmail()
{
return $this->myemail;
}
/**
* #param string $email
*/
public function setmyEmail($email)
{
$this->myemail = $email;
}
}
I want to write a php unit tests to test the private variables in this class but I am not sure how to test the variable $myPrefix because it does not have a setter ? Do I need to create a mock class ?
Thanks
You can do a simple test to ensure the initial value is null by simply testing the return from the class. Then use your Setter or __construct() to populate the field, and test the return from the getter again.
Optionally, and you do not need to go to this level of testing internal private fields as they should not change from outside the module, you can use Reflection.
I have some library classes that do things based on inputs, and I do use reflection to test the odd setting to be updated/set as I would expect for the function/method to work properly. This is done sparingly as the private values should not be changed external to the code library, but the test is for developer documentation purposes, and to ensure the basic functionality and assumptions in the code are not broken.
From the PHP Manual
$class = new ReflectionClass('myClass');
$property = $class->getProperty('myPrefix');
$this->assertEquals("Something from your setter", $property);
I would only use this to ensure that the set method (or constructor) is directly setting the field, not manipulating it in any way. However, with a get method, this is not needed since the get..() can test this. I only added the quick reference code to show you could test a value that did not have a get method.
I'm trying to get NetBeans 6.8 code completion to work for this. It doesn't seem to do it by itself, but I'm wondering if there's some phpdoc magic or something that may help, since it seems pretty darn good at using that.
Take the following two classes:
class A {
public $B;
public function __construct() {
$this->B = new D();
}
public function C() {
echo "C";
}
}
class D {
public $E;
public function __construct() {
// Do stuff.
}
public function F() {
echo "F";
}
}
Now, let's say I do $A = new A(); and then start typing $A->B->
Assuming that both classes are defined in the same file, this works perfectly. I get code complete suggestions for the E variable and the F method.
However, if the classes are split up into A.php and D.php respectively, and included into another file (say, index.php), doing the same thing after including both files gives only No Suggestions.
Any ideas? Thanks in advance!
I think netbeans doesn't look at the actual includes you do, but rather at the project's include path. Set that, and it should work. The reason probably has to do with the fact that most people use autoloading anyway, and following that would be a bit too much to ask.
It works for me in most cases, but if you have problems use /* #var $variable ClassName */ before line with $A = new A()
You can use a shortcut for this: type vdoc and press tab.
To extend upon Mchl's anwser:
If both files are in your project, and you use correct doc-blocks, code completion will find what you're looking for. To give an example:
/**
* Class A
*
* #author Yourname <And#Email>
* #package Example
*/
class A {
/**
* #var D
*/
public $B;
/**
* Constructor
*/
public function __construct() {
$this->B = new D();
}
/**
* Function C
*
* #return string
*/
public function C () {
return "C";
}
}
Typing the /** and hitting enter right before a method or variable will trigger the creation of such a block, provided it has been written already...