当前位置: 动力学知识库 > 问答 > 编程问答 >

php - Can I centralize code that's identical but needs two different method names to properly work?

问题描述:

In my job, I have a lot of data to import coming from various sources that have a tendency to give "unclean" information (missing fields, typos everywhere, you name it). As such I've built a framework to automate the various verifications that need to be done for data to become suitable for production. The thing is built in PHP and I took a lot of inspiration from PHPUnit in how my thing works. Here's a part of my basic class:

abstract class importUnitTest

{

public function __construct($nomTable, $conn, $niveauOutput = self::OUTPUT_ALL)

{

$this->nomTable = $nomTable;

$this->conn = $conn;

$this->testsReussis = true;

$this->niveauOutput = $niveauOutput;

$this->sql = "";

$methods = get_class_methods($this);

echo "<table class='tblUnitTest' id=\"unitTestResults\" border='1'>\n";

forEach($methods as $method)

{

if($method != '__construct' && preg_match("/^test/", $method))

{

$this->{$method}();

}

}

echo "</table>\n";

}

}

Basically, what it does is, upon instanciation, it'll loop through every method of my class and execute all those that start with test. So, when I have a new type of file to test, I simply extend a class and code my verification as follow:

class FACT_UnitTests_BT_BC extends importUnitTest

{

public function test__Assureur__NotNullOrEmpty($actif = true)

{

$res1 = $this->champNotNull($this->getNomChamp(__FUNCTION__), $actif);

$res2 = $this->champNotEmpty($this->getNomChamp(__FUNCTION__), $actif);

if(!$actif)

$resultat = self::TEST_DESACTIVE;

else

$resultat = ($res1 == self::TEST_REUSSI && $res2 == self::TEST_REUSSI) ? self::TEST_REUSSI : self::TEST_ECHOUE;

$this->genererOutput($this->getNomTestCourant(__FUNCTION__), $resultat);

$this->testsReussis = ($this->testsReussis && ($resultat !== self::TEST_ECHOUE));

$this->sql = "";

}

public function test__NoAssureur__NotNull($actif = true)

{

$resultat = $this->champNotNull($this->getNomChamp(__FUNCTION__), $actif);

$this->genererOutput($this->getNomTestCourant(__FUNCTION__), $resultat);

$this->testsReussis = ($this->testsReussis && ($resultat !== self::TEST_ECHOUE));

$this->sql = "";

}

public function test__NoClient__NotNull($actif = true)

{

$resultat = $this->champNotNull($this->getNomChamp(__FUNCTION__), $actif);

$this->genererOutput($this->getNomTestCourant(__FUNCTION__), $resultat);

$this->testsReussis = ($this->testsReussis && ($resultat !== self::TEST_ECHOUE));

$this->sql = "";

}

}

This all works perfectly and allows me to automate pretty much any verification I want. However, you probably noticed that methods "NoAssureur__NotNull" and "NoClient__NotNull" have the exact same code. In a normal case, same code = same function... but in this particular case, I need the function name in order to properly determine what field I'm testing (as you probably guessed one would be NoClient and the other NoAssureur).

Lately, I found a tiny mistake in one of my tests... and I had to go back and correct it in over a hundred places (since I'm obviously copy-pasting). That's rather unacceptable maintenance-wise. So is there a better way of going about things? Is there a way to centralize test code that's the same?

Thanks in advance,

Osu

网友答案:

I would set the test code in the abstract class with a field parameter and call it within the sub class with the parameter.

Something like this (parts of your actual code ommited, and a little unsure as I don't know where you're other methods are at all) :

abstract class importUnitTest
{
    public function isNotNull($field,$actif) {
        $resultat = $this->champNotNull($this->getNomChamp($field), $actif);
        $this->genererOutput($this->getNomTestCourant($field), $resultat);
        $this->testsReussis = ($this->testsReussis && ($resultat !== self::TEST_ECHOUE));
        $this->sql = "";
    }

//[...] omitting existing code
}


class FACT_UnitTests_BT_BC  extends importUnitTest
{
   // Omission of actual code

    public function test__NoAssureur__NotNull($actif = true)
    {
        $this->isNotNull(__FUNCTION__, $actif)
    }

    public function test__NoClient__NotNull($actif = true)
    {
        $this->isNotNull(__FUNCTION__, $actif)
    }
}

Again it's what came on top of my head, I may be wrong ;)

分享给朋友:
您可能感兴趣的文章:
随机阅读: