1

I am building a scheduler that will take a callback function and will execute that function a given amount of times, and in between a given amount of delay. Below is that the interface for what the functionality looks like.

Side note I am using the Laravel Framework;

public function testBasicTest()
{
    $count = 0;
    $schedule = new NodeScheduler();
    $schedule->retries(2)->delay(100000)->do(function() use ($count) {
        $count++;
    });
    $this->assertEquals($count === 1);
}

This is my test for this piece of functionality and as you can see i want count to equal 2 by the end of it.

My class looks like this;

class NodeScheduler
{
    protected $retries = 1;
    protected $milliseconds = 10000;

    public function __construct()
    {
        return $this;
    }

    public function retries($numberOfRetries)
    {
        $this->retries = $numberOfRetries;
        return $this;
    }

    public function delay($milliSeconds)
    {
        $this->milliSeconds = $milliSeconds;
        return $this;
    }

    public function do($callback)
    {
        for($i = 0; $i < $this->retries; $i++){
            $callback(); // <<<<<< How Do I Inject The $count Variable Here?
            usleep($this->milliseconds);
        }
        return;
    }
}

My test fails with:

Failed asserting that 2 matches expected 0.

Strangely I don't get $count is undefined.

I think i am close, any help greatly appreciated

1
  • I think you want to write $this->assertEquals(1, $count); Commented Oct 6, 2017 at 8:25

2 Answers 2

3

When you use() a variable from the outer scope inside a function, this creates a copy of the variable into the function's inner scope (an exception is if you're use()ing an object).

If you want to import a variable from the outer scope and modify it, you'll need to pass it in by reference:

$schedule->retries(2)->delay(100000)->do(function() use (&$count) {
    $count++;
});

Edit: Also, what @Arno and @Oniyo pointed out: either use assertEquals(1, $count) or use assertTrue($count === 1)

Sign up to request clarification or add additional context in comments.

1 Comment

I had no idea about the pass by reference, thank you very much
0

I think you are doing two things wrong

Firstly: As @Arno pointed out,

$this->assertEquals($expected, $actual);

Secondly: From what I see in your code, the loop will run $this->retries's iterations. So, $this->assertEquals($expected, $actual) should be

$this->assertEquals(2, count);

Good luck man!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.