नकली मैंने कुछ साल पहले ज़ेन फ्रेमवर्क को this tutorial के बाद सीखना शुरू किया था। वहां, यह दिखाता है कि डेटाबेस कनेक्शन प्राप्त करने के लिए Zend\Db\Adapter\Adapter
कक्षा का उपयोग करके मैपर बनाए जाते हैं, और इस तरह मैंने बिना किसी समस्या के डेटाबेस के साथ काम किया है।ज़ेंड फ्रेमवर्क 2 और PHPUnit - ज़ेंड डीबी एडाप्टर एडाप्टर क्लास
अब मैं सीखने की कोशिश कर रहा हूं कि ज़ेंड अनुप्रयोगों पर PHPUnit का उपयोग कैसे करें, और मैपर में फ़ंक्शंस का परीक्षण करने में कठिनाइयों में भाग ले रहा हूं क्योंकि मैं Zend\Db\Adapter\Adapter
कक्षा का नकल करने में असमर्थ हूं।
This tutorial ज़ेंड वेबसाइट पर डेटाबेस कनेक्शन का मज़ाक उड़ाता है, लेकिन यह Zend\Db\TableGateway\TableGateway
कक्षा का उपयोग करता है। अन्य सभी ट्यूटोरियल मैं ऑनलाइन पाया है Zend\Db\Adapter\Adapter
वर्ग के बारे में भी इस वर्ग का उपयोग करें, और केवल एक चीज मैंने पाया this है:
$date = new DateTime();
$mockStatement = $this->getMock('Zend\Db\Adapter\Driver\Pdo\Statement');
$mockStatement->expects($this->once())->method('execute')->with($this->equalTo(array(
'timestamp' => $date->format(FormatterInterface::DEFAULT_DATETIME_FORMAT)
)));
$mockDbDriver = $this->getMockBuilder('Zend\Db\Adapter\Driver\Pdo\Pdo')
->disableOriginalConstructor()
->getMock();
$mockDbAdapter = $this->getMock('Zend\Db\Adapter\Adapter', array(), array($mockDbDriver));
$mockDbAdapter->expects($this->once())
->method('query')
->will($this->returnValue($mockStatement));
मैं अपने setUp
विधि में है कि डाल लेकिन पर phpunit
चल कोशिश की है
Fatal error: Call to a member function createStatement() on null in C:\Program Files (x86)\Zend\Apache2\htdocs\test_project\vendor\zendframework\zend-db\src\Sql\Sql.php on line 128
तो मेरे सवाल का, तुम कैसे PHPUnit में Zend\Db\Adapter\Adapter
वर्ग नकली करते है: परीक्षण वर्ग मुझे निम्न त्रुटि देता है?
मैंने देखा है this question जो समान है, लेकिन Zend/Db/Adapter/AdapterInterface
इसके बजाय, और मैं उस स्थिति को अपनी स्थिति में अनुवादित नहीं कर सकता। नीचे मैपर और टेस्ट क्लास कोड।
ProductMapper.php:
public function __construct(Adapter $dbAdapter) {
$this->dbAdapter = $dbAdapter;
$this->sql = new Sql($dbAdapter);
}
public function fetchAllProducts() {
$select = $this->sql->select('products');
$statement = $this->sql->prepareStatementForSqlObject($select);
$results = $statement->execute();
$hydrator = new ClassMethods();
$product = new ProductEntity();
$resultset = new HydratingResultSet($hydrator, $product);
$resultset->initialize($results);
$resultset->buffer();
return $resultset;
}
ProductMapperTest.php:
public function setUp() {
$date = new DateTime();
$mockStatement = $this->getMock('Zend\Db\Adapter\Driver\Pdo\Statement');
$mockStatement->expects($this->once())->method('execute')->with($this->equalTo(array(
'timestamp' => $date->format(FormatterInterface::DEFAULT_DATETIME_FORMAT)
)));
$mockDbDriver = $this->getMockBuilder('Zend\Db\Adapter\Driver\Pdo\Pdo')->disableOriginalConstructor()->getMock();
$this->mockDbAdapter = $this->getMock('Zend\Db\Adapter\Adapter', array(), array(
$mockDbDriver
));
$this->mockDbAdapter->expects($this->once())->method('query')->will($this->returnValue($mockStatement));
}
public function testFetchAllProducts() {
$resultsSet = new ResultSet();
$productMapper = new ProductMapper($this->mockDbAdapter);
$this->assertSame($resultsSet, $productMapper->fetchAllProducts());
}
संपादित करें # 1:
का पालन करें विल्ट के जवाब से पर ing, मैं निर्माता में Sql
वर्ग का उपयोग करने के लिए अपने नक्शाकार बदल गया है और करने के लिए अपने टेस्ट वर्ग बदल दिया है:
public function setUp() {
$mockSelect = $this->getMock('Zend\Db\Sql\Select');
$mockDbAdapter = $this->getMockBuilder('Zend\Db\Adapter\AdapterInterface')->disableOriginalConstructor()->getMock();
$this->mockStatement = $this->getMock('Zend\Db\Adapter\Driver\Pdo\Statement');
$this->mockSql = $this->getMock('Zend\Db\Sql\Sql', array('select', 'prepareStatementForSqlObject'), array($mockDbAdapter));
$this->mockSql->method('select')->will($this->returnValue($mockSelect));
$this->mockSql->method('prepareStatementForSqlObject')->will($this->returnValue($this->mockStatement));
}
public function testFetchAllProducts() {
$resultsSet = new ResultSet();
$this->mockStatement->expects($this->once())->method('execute')->with()->will($this->returnValue($resultsSet));
$productMapper = new ProductMapper($this->mockSql);
$this->assertSame($resultsSet, $productMapper->fetchAllProducts());
}
हालांकि, अब मैं निम्नलिखित त्रुटि मिलती है:
ProductTest\Model\ProductMapperTest::testFetchAllProducts Failed asserting that two variables reference the same object.
है कौन सा $this->assertSame($resultsSet, $productMapper->fetchAllProducts());
लाइन से आ रहा है। क्या मैंने कुछ गलत तरीके से मजाक किया है?
# 2 संपादित करें:
विल्ट ने सुझाव दिया है, मैं परीक्षण वर्ग एक StatementInterface
का उपयोग करने के बजाय एक बयान उपहास करने के लिए, बदला तो कोड अब लगता है कि:
public function setUp() {
$mockSelect = $this->getMock('Zend\Db\Sql\Select');
$mockDbAdapter = $this->getMockBuilder('Zend\Db\Adapter\AdapterInterface')->disableOriginalConstructor()->getMock();
$this->mockStatement = $this->getMock('Zend\Db\Adapter\Driver\StatementInterface');
$this->mockSql = $this->getMock('Zend\Db\Sql\Sql', array('select', 'prepareStatementForSqlObject'), array($mockDbAdapter));
$this->mockSql->method('select')->will($this->returnValue($mockSelect));
$this->mockSql->method('prepareStatementForSqlObject')->will($this->returnValue($this->mockStatement));
}
public function testFetchAllProducts() {
$resultsSet = new ResultSet();
$this->mockStatement->expects($this->once())->method('execute')->with()->will($this->returnValue($resultsSet));
$productMapper = new ProductMapper($this->mockSql);
$this->assertSame($resultsSet, $productMapper->fetchAllProducts());
}
लेकिन परीक्षण केस अभी भी उपरोक्त के रूप में विफल रहा है। मैंने कोड की रेखा को नहीं बदला है जो execute
विधि का मज़ाक उड़ा रहा है क्योंकि मुझे लगता है कि यह पहले से ही $resultsSet
लौटा रहा है, हालांकि मैं गलत हो सकता था!
ग्रेट उत्तर धन्यवाद, मुझे एक 'एसक्यूएल' उदाहरण का उपयोग करने के लिए निर्भरता को बदलने की सही दिशा में इंगित किया। अब मैंने त्रुटि संदेश से छुटकारा पा लिया है, लेकिन परीक्षण खुद विफल रहा है जहां मैं इसे पारित करने की अपेक्षा करता हूं। यदि आपने कोई नज़र डालने पर ध्यान नहीं दिया है तो मैंने प्रश्न में नया कोड जोड़ा है? मुझे यकीन नहीं है कि मैंने कुछ गड़बड़ कर ली है, या यह सिर्फ यूनिट परीक्षण में अनुभव की कमी है और मैं गलत तरीके से परीक्षा उत्तीर्ण कर रहा हूं! – crazyloonybin
@ क्राज़िलोनीबिन एक कथन का नकल करने के लिए 'स्टेटमेंट इंटरफेस' का उपयोग करने के लिए पर्याप्त होगा (इसके लिए एक विशिष्ट एडाप्टर क्लास की आवश्यकता नहीं है)। फिर आपको इस '$ mockStatement' में 'execute' विधि का नकल करने की आवश्यकता है और इस विधि का वापसी मान' $ resultsSet' होना चाहिए। तब आपका परीक्षण पास होना चाहिए। – Wilt
मैंने '$ this-> mockStatement = $ this-> getMock ('ज़ेंड \ डीबी \ एडाप्टर \ ड्राइवर \ स्टेटमेंट इंटरफेस') पढ़ने के लिए कथन बदल दिया है, लेकिन मुझे अभी भी एक ही त्रुटि मिल रही है। मैंने '$ this-> mockStatement' कोड को प्रश्न संपादन में दिखाए गए जैसा ही रखा है, 'testFetchAllProducts' फ़ंक्शन' $ resultsSet' वापस लौटा रहा है - क्या इस लाइन को भी संशोधित करने की आवश्यकता है? – crazyloonybin