What you describe is a typical problem. The easiest way to solve it is to use so called mock objects. These objects behave like they are a real object, but in fact they are just a thin shell. Plus: you have full control over them in your test.
There are different ways to use mock objects, SimpleTest even has it's own implementation. Or you could use a framework like mockery.
In your case, you need a database connection object (DatabaseConnection
) with a query()
method. This returns you a result object (Result
), which in turn has a fetchAll()
method and returns probably an array.
I first declare two interfaces, this allows SimpleTest to mock the methods. If you already have declared classes for them you can just use them in Mock::generate()
to generate a mock class.
interface DatabaseConnection
{
function query();
}
interface Result
{
function fetchAll();
}
//this call generates a class called 'MockDatabaseConnection'
//with the same interface as 'DatabaseConnection'
Mock::generate('DatabaseConnection');
Mock::generate('Result');
class TestOfMember extends UnitTestCase
{
//this method gets called before each test method, it sets up each test
function setUp() {
$mockResult = new MockResult();
//here I just return a string, but you could return a Member object as well
$mockResult->returns('fetchAll', array("Member 1", "Member 2", "Member 3"));
$this->mockConn = new MockDatabaseConnection();
$this->mockConn->returns('query', $mockResult);
}
function testGetMembersFromEmailAddress() {
$conn = new MockDatabaseConnection();
//here you could now check for the mocked values "Member 1", "Member 2" ...
$this->assertTrue(Member::getMembersFromEmailAddress("xxx@xxx.com", $this->mockConn)==null);
$this->assertTrue(Member::getMembersFromEmailAddress("xxx@gmail.com", $this->mockConn)!=null);
}
}