Câu hỏi phpunit tránh các đối số hàm tạo cho mô phỏng


Cách để tránh phpunit phải gọi hàm tạo cho một đối tượng giả? Nếu không, tôi sẽ cần một đối tượng giả như đối số constructor, một số khác cho rằng vv Các api có vẻ như thế này:

getMock($className, $methods = array(), array $arguments = array(),
        $mockClassName = '', $callOriginalConstructor = TRUE,
        $callOriginalClone = TRUE, $callAutoload = TRUE)

Tôi không làm cho nó hoạt động. Nó vẫn phàn nàn về đối số hàm tạo, ngay cả với $callOriginalConstructor đặt thành false.

Tôi chỉ có một đối tượng trong hàm tạo và nó là một tiêm phụ thuộc. Vì vậy, tôi không nghĩ rằng tôi có một vấn đề thiết kế ở đó.


76
2017-11-10 23:00


gốc




Các câu trả lời:


Bạn có thể dùng getMockBuilder Thay vì chỉ getMock:

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

Xem phần trên "Kiểm tra đôi" trong Tài liệu PHPUnit để biết chi tiết.

Mặc dù bạn có thể làm điều này, tốt hơn hết là không cần. Bạn có thể cấu trúc lại mã của bạn để thay vì một lớp cụ thể (với một hàm tạo) cần được tiêm, bạn chỉ phụ thuộc vào một giao diện. Điều này có nghĩa là bạn có thể giả lập hoặc stub giao diện mà không cần phải nói với PHPUnit để sửa đổi hành vi của hàm tạo.


125
2018-06-08 10:11



Điều này làm việc tuyệt vời cho tôi. Đó là ví dụ 10.3, mặc dù. Tôi đã cố gắng chỉnh sửa bài đăng nhưng SO đã khởi động lại để chỉnh sửa quá ngắn. - Matthew
Cảm ơn @Lytithwyn. Đã cập nhật câu trả lời. - dave1010
cũng làm việc cho tôi. Cảm ơn! - Jeune


Ở đây bạn đi:

    // Get a Mock Soap Client object to work with.
    $classToMock = 'SoapClient';
    $methodsToMock = array('__getFunctions');
    $mockConstructorParams = array('fake wsdl url', array());
    $mockClassName = 'MyMockSoapClient';
    $callMockConstructor = false;
    $mockSoapClient = $this->getMock($classToMock,
                                     $methodsToMock,
                                     $mockConstructorParams,
                                     $mockClassName,
                                     $callMockConstructor);

40
2018-03-09 22:38



Điều này có vẻ là gần như những gì tôi muốn. Tôi muốn gọi getMock với lớp duy nhất để được chế giễu và $ callMockConstructor. Làm sao? một cái gì đó như thế này: $ this-> getMock ($ classToMock, $ callMockConstructor). Điều duy nhất tôi có thể nghĩ đến là đi vào nguồn PHPUnit và thay đổi nó thành mặc định = false. - Gutzofter
Tôi đã thay đổi mặc định thành false trong testcase.php. Bạn sẽ nghĩ rằng nó sẽ được đặt cho false theo mặc định. Mocking một constructor có vẻ rất kỳ quặc - Gutzofter
OBTW, Cảm ơn bạn! - Gutzofter
Câu trả lời tuyệt vời. Chỉ cần những gì tôi đang tìm kiếm - Hades


Là phụ lục, tôi muốn đính kèm expects() các cuộc gọi đến đối tượng giả của tôi và sau đó gọi hàm tạo. Trong PHPUnit 3.7.14, đối tượng được trả về khi bạn gọi disableOriginalConstructor() theo nghĩa đen là một đối tượng.

// Use a trick to create a new object of a class
// without invoking its constructor.
$object = unserialize(
sprintf('O:%d:"%s":0:{}', strlen($className), $className)

Thật không may, trong PHP 5.4 có một tùy chọn mới mà họ không sử dụng:

ReflectionClass :: newInstanceWithoutConstructor

Vì điều này không có sẵn, tôi phải tự phản ánh lớp và sau đó gọi hàm tạo.

$mock = $this->getMockBuilder('class_name')
    ->disableOriginalConstructor()
    ->getMock();

$mock->expect($this->once())
    ->method('functionCallFromConstructor')
    ->with($this->equalTo('someValue'));

$reflectedClass = new ReflectionClass('class_name');
$constructor = $reflectedClass->getConstructor();
$constructor->invoke($mock);

Lưu ý, nếu functionCallFromConstruct Là protected, bạn đặc biệt phải sử dụng setMethods() sao cho phương pháp được bảo vệ bị nhạo báng. Thí dụ:

    $mock->setMethods(array('functionCallFromConstructor'));

setMethods() phải được gọi trước expect() gọi điện. Cá nhân, tôi chuỗi này sau disableOriginalConstructor() nhưng trước đó getMock().


3
2018-03-08 02:21





Có lẽ bạn cần tạo một stub để truyền vào làm đối số hàm tạo. Sau đó, bạn có thể phá vỡ chuỗi các đối tượng giả.


1
2017-12-01 22:30



bạn có thể vui lòng chia sẻ thêm một số thông tin - Deep Singh Baweja


Hoặc bạn có thể thêm thông số vào getMock để ngăn chặn việc gọi hàm dựng mặc định.

$mock = $this->getMock(class_name, methods = array(), args = array(), 
        mockClassName = '', callOriginalConstructor = FALSE);

Tuy nhiên, tôi nghĩ rằng câu trả lời của dave1010 trông đẹp hơn, đây chỉ là vì lợi ích của sự hoàn chỉnh.


1
2017-07-21 07:37





PHPUnit được thiết kế để gọi hàm tạo trên các đối tượng giả; để ngăn chặn điều này, bạn nên:

  1. Tiêm một đối tượng giả làm phụ thuộc vào đối tượng bạn đang gặp sự cố
  2. Tạo một lớp thử nghiệm mở rộng lớp bạn đang cố gắng gọi mà không gọi hàm tạo của cha

0
2017-12-08 21:08