Thursday, April 14, 2011

Googlemock: Mock Object 應用於 C++ RAII 實例

在 Unit Test 中,Mocking 的技巧是用假的元件去取代受測元件所依賴的外部元件,稱為 Mock Object。測試者藉由控制 Mock Object 去可以改變受測元件的內部流程、或是驗證受測元件與外部元件的互動行為。

在 C++ 當中,常常慣用 RAII 的技巧,讓 Object 在進入 Function/Block 的範圍內獲取資源,離開範圍內釋放資源。舉例來說:
void example()
{
  File file("output.log");
  file.write("test");
}
在這種情況下,通常都會在測試程式中另外實作一組假的 File。不過,因為 Object 生成的時機是在進入受測的函式中,沒有機會用 ON_CALL 去控制 Mock Object 的行為。

所幸,你可以用下面的方式將 File 的實作,交給另外一個擁有相同介面的類別。這麼一來,我們還是可以控制這個新的類別。
// MockFile 是真正使用 Googlemock 的類別
class MockFile
{
public:
  MOCK_METHOD0(write, void(
    char *szLine));
};

MockFile *g_pMockFile = NULL;

// 將 File::write 導到 MockFile 上
File::write(char *szLine) 
{ 
  g_pMockFile->write(szLine); 
};

TEST_F(TestSuite, test_file_write)
{
  MockFile mockFile;
  EXPECT_CALL(mockFile, write(_));

  // 設定給 File::write() 使用這個 Mock Object
  g_pMockFile = &mockFile;

  example();
}
如此一來,就可以使用 Googlemock 幫我們取代掉 RAII 技巧所使用的類別。

No comments: