$this->assert* vs self::assert*

The assertion methods are declared static and can be invoked from any context using PHPUnit\Framework\Assert::assertTrue(), for instance, or using $this->assertTrue() or self::assertTrue(), for instance, in a class that extends PHPUnit\Framework\TestCase.

A common question, especially from developers new to PHPUnit, is whether using $this->assertTrue() or self::assertTrue(), for instance, is “the right way” to invoke an assertion. The short answer is: there is no right way. And there is no wrong way, either. It is a matter of personal preference.

I see self::assert* more and more I even reverted some PR’s because of it to enforce consistency at least in the same package. Today I asked @mwop what to do in zendframework. This was his answer:

Whenever I see self::, I just change those to $this-> when merging.

So basically the PR’s are like a ping pong game. Some are changing it to self:: and the next PR others are changing it to $this-> and vice versa. self:: is used all over the place.

Without an official statement we can’t tell contributors what to use in their PR’s. And from experience I know a quote from a private slack group is not good enough to stop the discussion :slight_smile:

I’d like to say only that I was defending $this->... for a long while, but recently I’ve started using self:: (as it is one character less, and easier to type :P)…

Definitely we should have consistency across all repositories, maybe even we should add it to coding-standard.

I would ping here @ocramius and @mwop because these two guys have different opinion (I guess :D). Thanks guys :slight_smile:

Thanks @xtreamwayz for opening this topic ! :+1:

A question for consideration: If i were to use codeception in replace of PHPUnit, would there be any side effects from using static asserts?

I suspect not, but I had to throw in the question.

Sebastian Bergmann says $this:

Or use the global function wrappers:
https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.static-vs-non-static-usage-of-assertion-methods

We use $this-> basically everywhere within the ZF repos, so standardizing on that is the path of least resistance.

As noted, I think the Assert:: syntax has use within closures as well as within traits; everywhere else, though, we should use $this->.

Yup, but the signature says static anyway. IIRC phpstan also clogs on
this, but I’d need to check.

Interesting: I do the opposite, changing $this-> to self:: while
merging.

Remember that the method is static, so static code analysis tools will
catch this as a violation at some point, and hopefully PHP will stop mixing
the two at some point in the future.

Why would I run static analysis on my test classes? I’m not sure I see any benefit to that, to be honest…

I run static analysis on test classes all the time: it finds parameter
mismatches, method signature issues, stub misuse and it prevents me from
writing impossible scenario tests

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

2 Likes

Remember that the method is static, so static code analysis tools will
catch this as a violation at some point

Really? Then I’d consider this an error in the static analysis tool. In PHP a static method can be called satically and non-statically, this is no logical error (since $this context does not apply to static methods, even if called non-static). Only calling non-static methods statically would be an error, since these require $this context. Sebastian states this: There ist nor right- or wrong-way to do it, just a matter of taste.

It is a mismatch in expectations: one is to call a function that may access
shared mutable global state, the other one is specific to the state of the
given object.

From a reader perspective, self:: is a strong indicator that the current
object state will not be modified, which is quite important. (yes, statics
that modify shared global state are bad!)

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

self:: is a strong indicator that the current object state will not be modified

Or read for that matter. It makes sense to call it statically, I may have to start using this myself.

I’m in the self:: boat myself (recently converted). There is no point in adding to the confusion by calling a static method non-statically. Just call it what it is.

Yeah, I also use self:: consistently. It’s declared static, and that tells me plainly the calls should be static, basically.

Actually I don’t mind how this will come out (As stated above, in PHP calling a static method non-statically does not matter).

But I’d like to raise awareness that a switch from $this-> to self:: would either result in inconsistent test-code or all components may need to be rewritten to use self::. Do we have the resources for this or can we live with the mixture for a while (or forever if nobody finds the time to contribute for a component)? Another thing is when a test expects an axception: This is done with $this->expectException() which is kind of an assertion that is not static. Also please note that the offical PHPUnit documentation shows all TestCase examples with $this->, so we might have to expect contributions with $this-> (e.g. https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertCount).

These are just my 2cents about this topic.

1 Like

Im all for ‘zelf::’. Actually went in and changed it until some maintainer started laughing really hard. So I shut up and thought nothing of it further.

Am glad others are worked up about this too…,

zelf:: ??? Dutch? :smiley:

1 Like

For me $this->something is natural whereas self::something is yet another weirdo from these so-called developers of Zend.

Let me fix that for you:

For me $this->something is natural whereas self::something I would not feel comfortable with if it was introduced by contributors to Zend Framework.

1 Like

Thats basically the same, but wrote differently…

The point with $this->sth is that its been used ever since, whereas self::sth has been invented out-of-nowhere just because sth had to change and developers had no idea what to chenge…

In other words => its been extremely stupid idea to introduce self::sth and force its usage by (progressively) making $this->sth deprecated…

And thats only one example of things invented because they have to invent sth… there are many more throughout PHP…

Whole Zend…

What I really miss much is pure PHP meaning from pre-Zend times… it was extremely nice programming language…