如何为此控制器创建单元测试?我知道如何制作功能,但不知道单元测试...
from task import variables
import filecmp, os
variables()
a=filecmp.cmp("test.txt","ans.txt")
if a == True:
print("Test Case Passed")
os.remove("test.txt")`
............................................... .................................................. .................................................. ..................
答案 0 :(得分:4)
有一个古老的笑话以#34开头;你如何让大象失望?" "你没有结束,你得到了一只鸭子"。仍然让我感到震惊。
关键在于,如果你让控制器的动作变得苗条,那么你可能根本不需要对它们进行单元测试。当然,100%的代码覆盖执行者会不同意这一点。
但是如果你决心测试它们,那么你需要做一些严肃的重构才能保持自己的理智。让我们来看看你的getAllAction:
public function getAllAction(Request $request)
{
$name = $request->query->get('name');
因此,您需要模拟一个请求对象,然后模拟一个bag对象,然后添加一个测试,以查看是否使用name参数调用了get。痛苦充其量。但是,Symfony实际上可以自动注入请求参数,所以:
public function getAllAction(string $name)
{
就是你所需要的。更少的代码。易于测试。什么不喜欢?
$result = $this->getDoctrine()->getRepository('AppBundle:Category')->findBy(array('name' => $name));
现在这可能是一个真正的问题。如果查看getDoctrine代码,您将看到它需要一个容器,该容器包含一个doctrine实体管理器注册表类,该类依次拥有一个实体管理器,然后该实体管理器保存存储库。你真的想要模仿所有这些对象并将它们串在一起吗?您将花费更多时间来调试测试,然后调试实际代码。作为奖励,您的代码在SF4中已经不再实际工作了,而SF4已经远离服务定位器模式。
幸运的是,使用动作注入很容易修复:
public function getAllAction(string $name, CategoryRepository $categoryRepository)
您将需要进行一些研究,以了解如何将存储库定义为服务,但测试并不困难且相当容易。我们再一次摆脱了相当讨厌的代码。
现在这有点有趣:
return new View("Catalog not found", Response::HTTP_NOT_FOUND);
对于单元测试,我们当然没有兴趣测试View类本身。相反,我们想知道的是View是否使用适当的参数构造。没有简单的方法来拦截新的行动。
相反,我们可以定义和注入ViewFactory
class ViewFactory
public create($data,$status)
return new View($data,$status)
所以现在很容易模拟视图工厂并测试create方法。作为奖励,控制器代码与View类没有太大关系。
因此,如果你真的觉得需要对这些行为进行单元测试,那么请卷起袖子开始重构。我可以补充说,在Symfony中查看新的autowire功能也是一个好主意。
答案 1 :(得分:1)
如果要使用单元测试隔离测试PHP类,则应该注入您在类中使用的所有服务。
作为一个起点:
/** @test */
public function it_should_return_a_view(){
$controller = new CatalogController();
$result = $controller->getAllAction($mockedRequest, $mockedRepository);
$this->assertInstanceOf(View::class, $result);
}
您需要模拟请求和存储库,这只有在您将其注入方法或通过构造函数注入类时才可能。
我希望这对你的单元测试有所帮助。