Php 如何使用此代码模拟对数据库的调用?

Php 如何使用此代码模拟对数据库的调用?,php,html,testing,mocking,Php,Html,Testing,Mocking,我正在修改代码以将其传递给对象,并想知道现在是否可以模拟对数据库的调用以使用PHPUnit执行单元测试,或者是否需要修改其他内容 具有数据库方法的类 <? php class methods { public function showData ($ sql) { $c = new connect(); $connection = $c->connection(); $result = mysqli_query ($conn

我正在修改代码以将其传递给对象,并想知道现在是否可以模拟对数据库的调用以使用PHPUnit执行单元测试,或者是否需要修改其他内容

具有数据库方法的类

<? php

class methods {
    public function showData ($ sql) {
        $c = new connect();
        $connection = $c->connection();

        $result = mysqli_query ($connection, $sql);
        return mysqli_fetch_all ($result, MYSQLI_ASSOC);
    }

    public function insertDataName ($data) {
        $c = new connect();
        $connection = $c->connection();

        $sql = "INSERT into agenda (nro_trans, user, anecdote, image)
                values ('$data[0]','$data[1]','$data[2]','$data[3]') ";

        return $result = mysqli_query($connection, $sql);
    }

为了模拟查询,您需要做两个更改

  • 注入连接对象,而不是在方法中实例化它
  • 使用面向对象的mysqli接口,而不是过程接口

  • 如果进行了这些更改,则可以使用必要的方法创建模拟对象。下面是一个使用匿名类的基本示例。您可以对其进行调整,使其在您决定执行的任何测试中尽可能复杂。如果您使用的是PHPUnit,那么可以使用其模拟对象设置类似的内容

    $mockConnection = new class {
        function connection() {
            return new class() {
                function query($sql) {
                    return new class() {
                        function fetch_all($fetchStyle) {
                            return [
                                ['col1Name' => 'col1ValueA', 'col2Name' => 'col2ValueA'],
                                ['col1Name' => 'col1ValueB', 'col2Name' => 'col2ValueB']
                            ];
                        }
                    };
                }
            };
        }
    };
    
    $testInstance = new methods($mockConnection);
    
    $testResult = $testInstance->showData('SELECT etc.');
    

    开玩笑???你的意思是做一个函数吗?好的代码缩进将帮助我们阅读代码,更重要的是,它将帮助你调试代码,为你自己谋福利。您可能会被要求在几周/几个月内修改此代码,最终您会感谢我。@RiggsFolly我想我必须修复sangria,但我仍然没有时间了解如何配置SublimiteText,我想让mock能够执行crud的单元测试,将mock与其他值进行比较,我/我们仍然不确定你想做什么,我认为“取笑”可能是一个翻译错误。虽然它通常是mock的同义词,但在这个上下文中,它的意思并不完全相同。如果我弄错了,我很抱歉。谢谢,我已经至少展示了依赖注入,只要我可以修改其余部分,并且我知道如何使用您添加的内容进行模拟,使用此示例来执行assertEquals就是要求我提供一个数组进行比较,这可能是因为我没有意识到
    <! DOCTYPE html>
    <html>
    <head>
    <meta charset = "utf-8">
    <meta http-equiv = "X-UA-Compatible" content = "IE = edge">
    <title> Tourism </title>
    <link href = 'http: //fonts.googleapis.com/css? family = Open + Sans: 400,700,400italic' rel = 'stylesheet' type = 'text / css'>
    <link rel = "stylesheet" href = "css / styles.css">
    <link rel = "stylesheet" href = "css / normalize.css">
    </head>
    <body>
    <header>
    
    <div class = "holder">
        <section class = "logo">
            <img src = "gallery / logo.jpg" alt = "logo">
        </section>
    
        <h1> National and International Tourism </h1>
    
        <div id = "facebook">
            <p> <a href="http://www.facebook.com/" target="_blank"> <img alt = "Follow us on Facebook" src = "https://lh6.googleusercontent.com/-CYt37hfDnQ8/ T3nNydojf_I / AAAAAAAAAr0 / P5OtlZxV4rk / s32 / facebook32.png "width = 32 height = 32 /> </a> </p>
        </div>
    
    </div>
    
    <div id = "twitter">
    
        <a href="http://twitter.com/" target="_blank"> <img src = "https://lh6.googleusercontent.com/--aIk2uBwEKM/T3nN1x09jBI/AAAAAAAAAs8/qzDsbw3kEm8/s32png "width = 32 height = 32 alt =" Follow us on Twitter "/> </a>
    </div>
    
    
    </header> <! - / header ->
    
    <nav>
        <div class = "holder">
    
        <ul>
            <li> <a href="index.php" title=""> Home </a> </li>
            <li> <a href="#"> Where do I travel? </a>
            <ul>
                <li> <a href="provincias.html"> Argentine Provinces </a> </li>
                <li> <a href="#"> Continents </a>
                <ul>
                    <li> <a href="vistas/america.html"> America </a> </li>
                    <li> <a href="vistas/europa.html"> Europe </a> </li>
                    <li> <a href="vistas/asia.html"> Asia </a> </li>
                 </ul>
            </ul>
            </li>
            </li>
            <li> <a href="services.html" title=""> Services </a> </li>
            <li> <a href="pay.html" title=""> Payment Methods </a> </li>
            <li> <a href="agenda.php" title=""> Agenda </a> <li>
            <li> <a href="contact.html" title=""> Contact </a> <li>
        </ul>
    </div>
    
    </nav>
    
    <section class = "holder">
        <h2> Traveler's agenda </h2>
            <div class = "column left">
                <p> Enter the anecdote you want to save. You have the option to delete and delete available if you are logged in to the page </p>
    
                <table style = "margin: auto; width: 800px; border-collapse: separate; border-spacing: 10px 5px;">
                  <thead>
                  <th> Nro Anecdota </th>
                  <th> User </th>
                  <th> Description </th>
                  <th> Image </th>
                  <th> <a href="agnewNew.php"> <button type = 'button' class = 'btn btn-info'> New </button> </a> </th>
    
    <? php
    $obj = new methods ();
    $sql = "SELECT * FROM agenda";
    $data = $obj-> show Data ($ sql);
    // show data on screen
    echo "<tr>";
        echo "<td>"; echo $row ['nro_trans']; echo "</td>";
        echo "<td>"; echo $row ['user']; echo "</td>";
        echo "<td>"; echo $row ['anecdote']; echo "</td>";
      // echo "<td>"; echo $row ['image']; echo "</td>";
        echo "<td>"; echo "<img src = '". $row ['image']. "' width = '300'>"; echo "</td>";
        echo "<td> <a href='modify.php?nro_trans=".$fila['nro_trans'[."'> <button type = 'button' class = 'btn btn-success'> Modify </button> </a> </td> ";
        echo "<td> <a href='eliminarAnecdota.php?nro_trans=".$fila['nro_trans'[."'> <button type = 'button' class = 'btn btn-danger' onclick = 'return ConfirmDelete() '> Remove </button> </a> </td> ";
    
    echo "</tr>";
    }
    ?>
    
    <script type="text/javascript">
    function ConfirmDelete () {
        var answer = confirm ("Are you sure you want the anecdote?");
    
        if (answer == true) {
            return true;
        } else {
        }
        return false;
    }
    </script>
    
        </thead>
        </table>
    </div>
    
    </section>
    
    <footer>
        <p>
        National and International Tourism
         Homemade Buenos Aires Argentina, Valentín Gómez 4772, B1678
         turismo_nacional_internacional@hotmail.com- Tel. / Fax: +54 11 4575-5012
        </p>
    
        <p> Copyright 2020: Design and Programming: Ezequiel Ledesma </p>
    </footer> 
    </body>
    </html>
    
    class methods {
    
        protected $connect;
    
        // This way you can inject either the real connection object or the mock
    
        public function __construct($connect) {
            $this->connect = $connect;
        }
    
        // Using object methods here rather than procedural functions that require
        // specific built-in objects like `mysqli_result` will let your method use
        // either the real connection or the mock
    
        public function showData($sql) {
            $connection = $this->connect->connection();
            $result = $connection->query($sql);
            return $result->fetch_all(MYSQLI_ASSOC);
        }
        // ... (make similar adjustments to the other methods)
    
    $mockConnection = new class {
        function connection() {
            return new class() {
                function query($sql) {
                    return new class() {
                        function fetch_all($fetchStyle) {
                            return [
                                ['col1Name' => 'col1ValueA', 'col2Name' => 'col2ValueA'],
                                ['col1Name' => 'col1ValueB', 'col2Name' => 'col2ValueB']
                            ];
                        }
                    };
                }
            };
        }
    };
    
    $testInstance = new methods($mockConnection);
    
    $testResult = $testInstance->showData('SELECT etc.');