List Info

Thread: Mock expectation question




Mock expectation question
user name
2008-04-09 09:02:49
Hello,

I'm having a problem defining certain mock expectations. In
my case, I only
care that method('param1', 'param2') is called only once and
at the same
time I don't care how many times it's called with any other
parameters. In
other words, method('param1', 'param2') MUST be called and
at the same time
method('foo', 'bar'), method('whatever', 'else')... MAY be
called any times.

The following

$mock->expectOnce('method', array('param1', 'param2'));

will fail as soon as the mock receives more than one
method() call or the
first call doesn't pass 'param1' and 'param2' as
parameters.

Is there a nice way to do what I need?

-- 
Regards,
Rytis
------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

Re: Mock expectation question
user name
2008-04-09 11:36:09
Hi...

Rytis Daugirdas wrote:
> The following
> 
> $mock->expectOnce('method', array('param1',
'param2'));
> 
> will fail as soon as the mock receives more than one
method() call or the
> first call doesn't pass 'param1' and 'param2' as
parameters.
> 
> Is there a nice way to do what I need?
> 

Not that I can see :(. Can you give us some more context?

It's possible that by cutting the test a different way we
can avoid 
such an intricate query. If not, then we can add it as a
feature 
request.

One workaround is to inherit the mock to create a custom
one. When I 
first used mock objects (pre SimpleTest) I had to write them
from 
scratch. It took just a day of this to convince me to write
the code 
generator you see now. Not expecting to cover every case, I
made 
sure you could intercept it with a subclass...

$Mock::generate('MyClass', 'IntermediateClass');
class MyMockClass extends IntermediateClass {
     ...
}

I hardly ever used this facility over the next four years.
This 
makes me think we can solve your problem with some kind of
style 
change, or that what you are doing is at the edge of the
envelope. 
If you are working at the margins the subclass trick is the
ultimate 
escape route.

But let's here more about your problem first .

yours, Marcus

------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

Re: Mock expectation question
country flaguser name
United Kingdom
2008-04-09 12:02:07
On Wed, 9 Apr 2008 16:02:49 +0200
"Rytis Daugirdas" <rytis.daugirdasgmail.com> wrote:

> Hello,
> 
> I only care that method('param1', 'param2') is called
only once and
> at the same time I don't care how many times it's
called with any
> other parameters.

There is expectAtLeastOnce but it seems to check for
parameter equality
on *every* call which means you get a lot of false errors.

However, you can drop in a custom expectation object instead
of the
parameters: 

$expectation = new ParameterMonitoringThing($param1,
$param2);
$foo->expectAtLeastOnce('bar', array($expectation));

This could monitor the arguments received in different
calls. Check you
got what you wanted at least once at the end of the test:

$this->assertTrue($expectation->hasReceivedExpectedPar
ameters());

Make sure ParameterMonitoringThing::test() always returns
true.
It's just be pretending to be a normal expectation object so
that
it can listen in to the parameters.


Noel

------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

Re: Mock expectation question
user name
2008-04-09 15:49:02
Hello,

I am very well aware that my approach might not be the best
since I still
consider myself very new to this TDD business. ;)

The context is pretty straightforward. My goal is a simple
validator of a
specific request, that is, it should validate a request
object. The request
object itself cannot be instantiated and used in the usual
way - there are
some dependencies which for some reason do not function
properly in PHP CLI
environment (please don't ask me why - I am not the author
of it, it's a
framework class). So I decided to mock it.

The validator object reads the parameters to validate from
the request (that
I can provide via setReturnValue()) and sets error messages
via
setError($id, $message) in the same request object (mock).
I'm trying to
make tests focused on single parameter validation
(testInvalidEmail(),
testInvalidPostcode(), etc). In these tests my goal is to
assert that
setError() has been called with the right parameters at
least once or, if
the request parameter is valid, that it hasn't been called
at all with those
parameters. Since the validator validates multiple request
parameters, if at
least one of them is invalid (besides the one under test),
setError() is
called "with the wrong parameters" and I get
expectation errors. For
example:

public function testEmptyEmail()
{
  // return an empty email
  $this->request->setReturnValue('getParameter', '',
array('email'));

  /* setError('email', 'Email is empty.') MUST be called
once, but I don't
care
     if the validator additionally calls setError('some
param', 'some
error') when
     validating other parameters. Thus the line below will
give me an
expectation error
     if setError() is called with different parameters even
though the
expectation might
     be met in some later setError() call. */
  $this->request->expectOnce('setError',
array('email', 'Email is empty.'));

 
$this->assertFalse($this->validator->validate($this
->request));
}

In short, I want to check that a method has or has not been
called with
certain parameters, but I do not care if it has or has not
been called with
others.

I hope I managed to explain the problem well enough.

Noel: Indeed, a custom expectation might be one of the
possible solutions
here. I'll take a closer look at them if I don't find a
cleaner way to do
what I need.

-- 
Regards,
Rytis

On Wed, Apr 9, 2008 at 7:02 PM, Noel Darlow <mailmcgruff.plus.com> wrote:

> On Wed, 9 Apr 2008 16:02:49 +0200
> "Rytis Daugirdas" <rytis.daugirdasgmail.com> wrote:
>
> > Hello,
> >
> > I only care that method('param1', 'param2') is
called only once and
> > at the same time I don't care how many times it's
called with any
> > other parameters.
>
> There is expectAtLeastOnce but it seems to check for
parameter equality
> on *every* call which means you get a lot of false
errors.
>
> However, you can drop in a custom expectation object
instead of the
> parameters:
>
> $expectation = new ParameterMonitoringThing($param1,
$param2);
> $foo->expectAtLeastOnce('bar',
array($expectation));
>
> This could monitor the arguments received in different
calls. Check you
> got what you wanted at least once at the end of the
test:
>
>
$this->assertTrue($expectation->hasReceivedExpectedPar
ameters());
>
> Make sure ParameterMonitoringThing::test() always
returns true.
> It's just be pretending to be a normal expectation
object so that
> it can listen in to the parameters.
>
>
> Noel
>
>
------------------------------------------------------------
-------------
> This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference
> Don't miss this year's exciting event. There's still
time to save $100.
> Use priority code J8TL2D2.
>
> http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
> _______________________________________________
> Simpletest-support mailing list
> Simpletest-supportlists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/simp
letest-support
>
------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

Re: Mock expectation question
country flaguser name
United States
2008-04-09 22:06:23
Rytis Daugirdas wrote:
> [snip] I hope I managed to explain the problem well
enough.

My first thought was that the expectOnce should work, but
since I don't
have easy access to a coding environment right now, here are
my thoughts:

- You may want to consider testing for all the errors. While
you are
trying to do focused tests (a commendable effort), if you
can't get
around the fact that there will be two or more errors in one
input, test
for all of them. I've been in a similar situation, but I've
always been
able to wheedle the input into a form where it has exactly
one error
(and I was using Exceptions, which means one and one only


- You were correct in mocking the validator. However, if you
find that
SimpleTest's default mock is insufficient for your purposes,
you might
want to extend the mock! (I've done it before; be sure to
generate the
mock before you extend it). Or, you can build a mock from
scratch.

- It sounds like you testing a whole battery of validations
at once.
While in certain cases this is fine (a very rigid set of
validation
procedures), a web application should probably have
composable
validations. That means you should be able to isolate each
of the
validations into their own method or class, and test them
individually.
That may help things out.

Anyways, the behavior you're describing sounds like a bug in
SimpleTest.
Marcus, any comments?

-- 
 Edward Z. Yang                        GnuPG: 0x869C48DA
 HTML Purifier <http://htmlpurifier.org&g
t; Anti-XSS Filter
 [[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA ]]

------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

Re: Mock expectation question
user name
2008-04-10 01:51:41
Hello, Edward,

- You may want to consider testing for all the errors. While
you are
> trying to do focused tests (a commendable effort), if
you can't get
> around the fact that there will be two or more errors
in one input, test
> for all of them. I've been in a similar situation, but
I've always been
> able to wheedle the input into a form where it has
exactly one error
> (and I was using Exceptions, which means one and one
only 
>

I really think the tests should be focused in this case.
"testEmptyEmail()"
documents the behavior related to that particular parameter
very clearly -
if it's empty, you get a particular error registered and
this test shouldn't
care whether any OTHER errors are registered for other
parameters or not.
Adding any additional expectations in this case would just
clutter the test,
I think.

- It sounds like you testing a whole battery of validations
at once.
> While in certain cases this is fine (a very rigid set
of validation
> procedures), a web application should probably have
composable
> validations. That means you should be able to isolate
each of the
> validations into their own method or class, and test
them individually.
> That may help things out.


The framework I use already has simple validators such as
email validator,
number validator etc. My request validator will certainly
use these classes,
but I'm really not going to test them. They are tested well
enough by their
original developers ;).

Thanks for your comments.

-- 
Regards,
Rytis

On Thu, Apr 10, 2008 at 5:06 AM, Edward Z. Yang <
edwardzyangthewritingpot.com> wrote:

> Rytis Daugirdas wrote:
> > [snip] I hope I managed to explain the problem
well enough.
>
> My first thought was that the expectOnce should work,
but since I don't
> have easy access to a coding environment right now,
here are my thoughts:
>
> - You may want to consider testing for all the errors.
While you are
> trying to do focused tests (a commendable effort), if
you can't get
> around the fact that there will be two or more errors
in one input, test
> for all of them. I've been in a similar situation, but
I've always been
> able to wheedle the input into a form where it has
exactly one error
> (and I was using Exceptions, which means one and one
only 
>
> - You were correct in mocking the validator. However,
if you find that
> SimpleTest's default mock is insufficient for your
purposes, you might
> want to extend the mock! (I've done it before; be sure
to generate the
> mock before you extend it). Or, you can build a mock
from scratch.
>
> - It sounds like you testing a whole battery of
validations at once.
> While in certain cases this is fine (a very rigid set
of validation
> procedures), a web application should probably have
composable
> validations. That means you should be able to isolate
each of the
> validations into their own method or class, and test
them individually.
> That may help things out.
>
> Anyways, the behavior you're describing sounds like a
bug in SimpleTest.
> Marcus, any comments?
>
> --
>  Edward Z. Yang                        GnuPG:
0x869C48DA
>  HTML Purifier <http://htmlpurifier.org&g
t; Anti-XSS Filter
>  [[ 3FA8 E9A9 7385 B691 A6FC B3CB A933 BE7D 869C 48DA
]]
>
------------------------------------------------------------
-------------
This SF.net email is sponsored by the 2008 JavaOne(SM)
Conference 
Don't miss this year's exciting event. There's still time to
save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;1987
57673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Simpletest-support mailing list
Simpletest-supportlists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/simp
letest-support

[1-6]

about | contact  Other archives ( Real Estate discussion Medical topics )