这是我的 PHPUnit 测试(PHPUnit 10.5.2 Mockery 1.6.11)
public function testMergedDocumentsWithSuccessfulInit() {
$params = new \Buan\Request\Parameters([], [], [], []);
$mockAdminView = m::mock(AdminView::class);
// The mocking of init method will consider the inheritance from Ias\AdminController.
$controller = m::mock('DocumentsController', [$params])
->makePartial()
->shouldAllowMockingProtectedMethods();
// Mock the 'init' method which is inherited from Ias\AdminController
$controller->shouldReceive('init')
->with($mockAdminView)
->andReturn(true)
->once(); // Ensure the init method is mocked to return true once
echo "Mock setup complete, testing init call\n";
$initResult = $controller->init($mockAdminView); // This should print true as the init method is mocked
echo "init called, result: " . ($initResult ? "true" : "false") . "\n";
// Execute the mergedDocuments method and check the result
$result = $controller->mergedDocuments();
这是我在 DocumentsController 上测试的方法的开始:
public function mergedDocuments(): AdminView
{
// Init
$view = new AdminView();
$initResult = $this->init($view);
if (!$initResult) {
return $view;
}
“init”方法在 DeveloperController 扩展的 AdminController 中定义,例如
class DocumentsController extends Ias\AdminController
DocumentsController 位于全局命名空间中,而 AdminController 位于 Ias 中(不确定这是否相关)。
无论我将“->andReturn(...)”设置为什么,总是会达到返回 $view,即“init”方法不会被拦截并正常运行,始终返回 false。
protected function init(AdminView $view, bool $bypassAuthCheck = false): bool
我的问题是,为什么init方法没有被拦截?
我期望通过将“andReturn”设置为 false,在我的 mergeDocuments 方法中不会达到早期返回。
我在 IDE 中注意到,当我将鼠标悬停在“init”函数上时,它显示:“成员具有受保护的可见性,但可以访问“__call”魔术调用方法”。我按如下方式更新了我的测试,这有效:
public function MergedDocumentsWithFailedInit()
{
$params = new \Buan\Request\Parameters([], [], [], []);
// Since DocumentsController extends Ias\AdminController, create a mock of DocumentsController.
// The mocking of init method will consider the inheritance from Ias\AdminController.
$controller = m::mock('DocumentsController', [$params])
->makePartial()
->shouldAllowMockingProtectedMethods();
// Mock the behavior of the __call method to delegate calls to init
$controller->shouldReceive('__call')
->with('init', m::on(function ($args) {
return count($args) == 1 && $args[0] instanceof AdminView;
}))
->andReturnUsing(function ($method, $args) use ($controller) {
return $controller->init(...$args);
});
// Mock the behavior of the init method to always return true
$controller->shouldReceive('init')
->andReturn(false);
$initResult = $controller->init($mockAdminView);
// Execute the mergedDocuments method and check the result
$result = $controller->mergedDocuments();
$this->assertInstanceOf(AdminView::class, $result);
}