Tek*_*Tek 10 service phpunit mocking symfony
我有需要的一类Symfony2服务@request_stack返回的一个实例Symfony\Component\HttpFoundation\RequestStack.我用它来检索POST和GET值.
也是我的类使用Symfony\Component\HttpFoundation\Session由Request->getSession()它调用来获得当前会话.
现在我的类有一个看起来像这样的方法:
class MyClass {
public function doSomething() {
//Get request from request stack.
$Request = $this->RequestStack->getCurrentRequest();
//Get a variable from request
$var = $Request->request->get('something');
//Processes $var into $someprocessedvar and lets say it's equal to 3.
//Set value to session.
$this->Request->getSession()->set('somevar', $someprocessedvar);
}
}
Run Code Online (Sandbox Code Playgroud)
我需要能够:
RequestStack.Request从RequestStackSession从Reques吨;尽管如此,我如何测试MyClass成功设置会话中的预期值?
并非所有代码都值得单元测试.通常这表明您的代码可以简化.当您对单个测试代码进行单元测试时,测试可能会成为一种负担,通常情况下,在这些情况下进行边对边测试的集成会更好.在你的例子中也不清楚你的类是如何得到的RequestStack所以我会假设它已被注入__construct.
这就是说你将如何测试该代码:
protected function setUp()
{
$this->requestStack = $this->getMock('Fully-qualified RequestStack namespace');
$this->SUT = new MyClass($this->requestStack);
}
/** @test */
public function it_should_store_value_in_the_session()
{
$value = 'test value';
$request = $this->getMock('Request');
$request->request = $this->getMock('ParameterBag');
$session = $this->getMock('Session');
$this->requestStack
->expects($this->atLeastOnce())
->method('getCurrentRequest')
->will($this->returnValue());
$request->request
->expects($this->atLeastOnce())
->method('get')
->with('something')
->will($this->returnValue($value));
$request
->expects($this->once())
->method('getSession')
->will($this->returnValue($session));
$session
->expects($this->once())
->method('set')
->with('somevar', $value);
$this->SUT->doSomething();
}
Run Code Online (Sandbox Code Playgroud)
这应该给你一个起点,但要注意你的测试中有一堆模拟,因为实现细节的微小变化会导致你的测试失败,即使行为仍然是正确的,这是你想要避免的事情.可能因此测试维护成本不高.
编辑:我想到了更多关于你的问题,并意识到通常你可以将Session作为依赖注入.如果在您的用例中可以实现,那么它将大大简化测试.
您无需嘲笑RequestStack,这是一个非常简单的类。您可以创建一个虚假请求并将其推送到该请求。您也可以模拟会话。
// you can overwrite any value you want through the constructor if you need more control
$fakeRequest = Request::create('/', 'GET');
$fakeRequest->setSession(new Session(new MockArraySessionStorage()));
$requestStack = new RequestStack();
$requestStack->push($fakeRequest);
// then pass the requestStack to your service under test.
Run Code Online (Sandbox Code Playgroud)
但是就测试而言,必须弄乱类的内部不是一个好兆头。也许您可以创建一个处理程序类来封装请求栈中所需的逻辑,以便您可以更轻松地进行测试。