当前位置: 首页 > 知识库问答 >
问题:

用具体的价值来模拟竞争,其余的不重要

武睿
2023-03-14

这个问题存在于PHP中,但适用于使用XUnit框架的任何语言。

我想要一个mock,它需要140次调用方法jump
我需要验证,至少有一次调用是以500作为参数的。
我不在乎是否所有调用都是500,但我需要至少一次调用是以500作为参数的。

$mock = $this->getMock('Trampoline', ['jump']);

$mock->expects($this->atLeastOnce())
     ->method('jump')
     ->with($this->equalTo(500))
     ->will($this->returnValue(true));

$sportsman->setTramploine($mock);
$sportsman->jumpToRandomHeights($times = 140); // this calls Trampoline->jump
// I need to verify the sportsman had jumped 
// to the height of 500 at least once out of the 140 jumps he is performing

缺少的信息片段是在中使用带有的回调。多亏了Edorian在下面的回答,这就是结果:

$testPassed = false;

$checkMinHeight = function ($arg) use(&$testPassed)
{
    if($arg === 500)
        $testPassed = true;

    // return true for the mock object to consider the input valid
    return true;
}


$mock = $this->getMock('Trampoline', ['jump'])
    ->expects($this->atLeastOnce())
    ->method('jump')
    ->with($checkMinHeight)
    ->will($this->returnValue(true));

$sportsman->setTramploine($mock);
$sportsman->jumpToRandomHeights($times = 1000); // this calls Trampoline->jump
// I need to verify the sportsman had jumped 
// to the height of 500 at least once out of the 1000 jumps he is performing


$this->assertTrue($testPassed, "Sportsman was expected to 
    jump 500m at least once");

共有1个答案

乐华晖
2023-03-14

但是我能想到的使用PHPUnits mocking API的最佳实现看起来仍然很令人毛骨悚然。

解决这个问题的另一个方法是更易读一点的方法是创建自己的trampoline子类并在那里实现它。

假设这样的类:

<?php
class FancyMocking {
    function doThing($value) { }
}
<?php

class FancyMockingTest extends PHPUnit_Framework_TestCase {

    public function testAtLeastOfMy200CallsShouldHaveAValueGreaterThan500() {
      $maxInvocations = 200;

      $mock = $this->getMock('FancyMocking');
      $mock->expects($this->exactly($maxInvocations))
        ->method('doThing')
        ->with($this->callback(function ($value) use ($maxInvocations) { 
            static $invocationCount = 0;
            static $maxValue = 0;

            $maxValue = max($value, $maxValue);
            /* The assertion function will be called twice by PHPUnit due to implementation details, so the *2 is a hack for now */
            if (++$invocationCount == $maxInvocations * 2) { 
                $this->assertGreaterThan(200, $maxValue, 'in 500 tries the max value didn\'t to over 200');
            } 
            return true;
        }))
        ->will($this->returnCallback(function ($value) { 
            return $value >= 200;
        }));
     for($i = $maxInvocations - 2; $i; --$i) { 
          $mock->doThing(50);
     } 
     var_dump($mock->doThing(250));
     var_dump($mock->doThing(50));
    }


}
PHPUnit 3.7.9 by Sebastian Bergmann.

.bool(true)
bool(false)


Time: 0 seconds, Memory: 2.75Mb

OK (1 test, 2 assertions)
PHPUnit 3.7.9 by Sebastian Bergmann.

Fbool(false)


Time: 0 seconds, Memory: 2.75Mb

There was 1 failure:

1) FancyMockingTest::testAtLeastOfMy200CallsShouldHaveAValueGreaterThan500
Expectation failed for method name is equal to <string:doThing> when invoked 200 time(s)
in 500 tries the max value didn't to over 200
Failed asserting that 70 is greater than 200.

.../FancyMockingTest.php:29

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

类FancyMockingFakeImplementation扩展了FancyMock,使用它来代替mock,并在其中编写自定义逻辑

 类似资料:
  • 问题内容: 是否可以使用EaskMock模拟具体的类?如果是这样,我该怎么办? 问题答案: 请参阅EasyMock类扩展文档,并从SourceForge项目下载它。但是,您不能模拟最终方法。 编辑:如注释中所述,这是EasyMock v3及更高版本的一部分。

  • 9.1. 竞争条件 在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的事件x和y的执行顺序,x是在y之前还是之后还是同时发生是没法

  • 例子 #include <pthread.h> int Global; void *Thread1(void *x) { Global = 42; return x; } int main(void) { pthread_t t; pthread_create(&t, NULL, Thread1, NULL); Global = 43; pthread_join(t, NU

  • 我有一个select,它给我带来了一些主键。我需要从上一个查询中未列出的其他表中选择所有值。我该怎么做? 我一直在尝试: 但不起作用,它还带来了子查询中的数据。我正在使用PostgreSQL。

  • 从我在internet上看到的情况来看,sonarqube使用其他第三方工具,如PMD、checksyle、findbugs来显示sonarlint所显示的以外的其他问题。 公司中通常由谁为PMD、Checkstyle等提供xml规则集?是声纳团队还是架构团队?或者项目团队领导创建一个并提供给团队。

  • 问题内容: 我在Google App Engine中遇到争用问题,并尝试了解发生了什么。 我有一个注释为的请求处理程序: ..并且在该代码中,我获取了一些东西,更新了其他东西,等等。但是有时在请求期间日志中会出现这样的错误: ..之后是堆栈跟踪。如果需要,我可以使用整个堆栈跟踪进行更新,但这有点长。 我不明白为什么会这样。查看我的代码行中的异常,我在一个完全不同的实体(Round)上运行。错误消息