Expectations & types

1 view
Skip to first unread message

Matthias Loitsch

unread,
Apr 27, 2010, 7:01:13 AM4/27/10
to snaptest
Hi,

I'm not quite sure on how to use the expectations...

1) Do I have to create a listener for every expectations, so I can
test for it later on with assertCallCount() ?
If so, why can't I just say that the class should listen to this
method, and test for the different expectations afterwards?

2) Can I create multiple listeners with different expectations for the
same method?

3) What exactly does the Snap_Anything_Expectation do? If it is to
test for anything, why can I pass a $type?


Thanks!

Matthias Loitsch

--
You received this message because you are subscribed to the Google Groups "snaptest" group.
To post to this group, send email to snap...@googlegroups.com.
To unsubscribe from this group, send email to snaptest+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/snaptest?hl=en.

Jakob Heuser

unread,
Apr 27, 2010, 11:44:24 AM4/27/10
to snap...@googlegroups.com
Expectations: http://wiki.github.com/Jakobo/snaptest/expectations-reference
Even though $type is on the superclass, it is not being utilized by
the match() method in the subclass. You can use an
anything_expectation to say that the params don't matter when creating
the mock object.

A listener is needed for the expectation, so that you can shunt the
original method. Think of expectations as ensuring sigantures for a
method, which can then be used with listenTo and assertCallCount

The file:
tests/mock/multiple_listento.stest.php has an example. It can be
simplified by storing the expectations as local variables during setup
(to minimize repeat typing).

Matthias Loitsch

unread,
Apr 27, 2010, 12:03:21 PM4/27/10
to snap...@googlegroups.com
Mh...

I don't really understand why setting the expectations when creating the listeners is necessary.

Theoretically: When I create a listener on an object, lets say: listenTo('foo'), snaptest could listen to all calls to foo.
If I then call:
$mock->foo();
$mock->foo(5);
$mock->foo(5, 'test');

the assertCallCount for foo, without expectation could be 3, with the expectation 5 it would be 2, and with 5 & 'test' only 1.

Asserting the call counts could just work the same.

I understand what the expectations in the listeners do now... I'm just what the benefit of it ist.


cheers, and thanks for the reply


Matthias Loitsch
m...@tthias.com

Jakob Heuser

unread,
Apr 27, 2010, 4:47:31 PM4/27/10
to snap...@googlegroups.com
You'd have to actually change the behavior of foo though to make sure
it record a call for a given signature. The primary use case is when
you need to tally, but don't want to alter the return value of the
method. in mock.php:

/**
* Tell the mock object to listen on a given set of params. This
enables tally options
* any method that has also been tagged with a setReturnValue gets
the listener as
* well. Use this primarily during setup to prepare to test Expectations
*/
public function listenTo($method_name, $method_params = array()) {
$method_params = $this->handleMethodParameters($method_params);
$method_signature = $this->getMethodSignature($method_name,
$method_params);
$this->logMethodSignature($method_name, $method_signature,
$method_params);
return $this;
}

Anything that receives setReturnValue() has a signature logged and can
be tallied without any issue. Sometimes though, you aren't able to
mock/shunt the method, but still need to ensure it's called.

Hope this helps!

Matthias Loitsch

unread,
Jul 13, 2010, 10:44:04 AM7/13/10
to snap...@googlegroups.com

Sorry to come back to this »issue«...

What I still can't really figure out, is why Snaptest doesn't simply use overloading to log *all* calls to the object.

http://www.php.net/manual/en/language.oop5.overloading.php

Why do you need to create a signature of the method & parameters in advance?
The mock object could just be a generic object, that catches all method calls, and attribute accesses, and checks if the class it should inherit from »supports« them. It could then go through the stored setReturnValue() calls, and see if it has to return something specific or not, and simply log the call, so you can ask later if it has been called...

Or am I missing something?


Thanks,

Matthias Loitsch
m...@tthias.com

Jakob Heuser

unread,
Jul 13, 2010, 1:27:44 PM7/13/10
to snap...@googlegroups.com
There's no particular reason other than inheritance. Type/Interface
support is the most significant reason, where you need to make sure
the mocked object supports all "instanceof" and is_class() type checks
that could exist in the code.

The other use case (seldom used, but sometimes required) is a partial
mock. You want the object to behave exactly like the original, only
with one or two methods altered.

Hope this helps.

Jakob

Reply all
Reply to author
Forward
0 new messages