2009-07-22 43 views
6

Sản phẩm hiện tại tôi đang làm là một Dịch vụ Windows được viết bằng C++ và chuyển tiếp tất cả các chức năng mới sẽ có các bài kiểm tra đơn vị được viết cho nó. Nhưng điều này tạo ra một vấn đề thú vị (đối với tôi ít nhất) chúng tôi thực hiện rất nhiều cuộc gọi Win32 cho nhiều thứ khác nhau và hành xử tương ứng, vì vậy để các bài kiểm tra đơn vị được hoàn thành, sẽ tốt hơn nếu kiểm tra nhiều đầu ra, không chỉ hệ thống hiện tại tiểu bang.Các cuộc gọi API Mocking và Win32

Câu hỏi của tôi là cách tốt nhất để thử kết quả của cuộc gọi Win32 là gì? Tôi đã nghĩ về hai phương pháp khác nhau:

1) Đặt tất cả các cuộc gọi Win32 được sử dụng vào con trỏ hàm và chuyển chúng vào các hàm hoặc lớp (tùy thuộc vào số lần chúng bị tấn công) sử dụng chúng và sử dụng các kết quả.

2) Có rất nhiều #ifdef UNITTEST ở khắp mọi nơi và nếu nó đang gọi các phương pháp đặc biệt của riêng tôi hoặc có các phương thức thông thường được gọi là nếu không.

Tôi hoàn toàn có cơ sở ở đây hay thiếu một phần kiến ​​thức cơ bản?

+1

Điều gì xảy ra nếu bạn cần đối số để sửa đổi hành vi của UnitTestMessageBox? #ifdef UNITTEST #undef MessageBox #define MessageBox UnitTestMessageBox #endif – Manolete

Trả lời

9

Đối với (2), hầu hết các hàm Win32 lấy tham số chuỗi đã có biểu mẫu chung được xác định là macro, ví dụ: từ WinUser.h:

WINUSERAPI 
int 
WINAPI 
MessageBoxA(
    __in_opt HWND hWnd, 
    __in_opt LPCSTR lpText, 
    __in_opt LPCSTR lpCaption, 
    __in UINT uType); 
WINUSERAPI 
int 
WINAPI 
MessageBoxW(
    __in_opt HWND hWnd, 
    __in_opt LPCWSTR lpText, 
    __in_opt LPCWSTR lpCaption, 
    __in UINT uType); 
#ifdef UNICODE 
#define MessageBox MessageBoxW 
#else 
#define MessageBox MessageBoxA 
#endif // !UNICODE 

Bạn chắc chắn có thể thêm một tiêu đề để dự án của bạn mà định nghĩa lại các hàm API mà bạn muốn để mô phỏng:

#ifdef UNITTEST 
#undef MessageBox 
#define MessageBox UnitTestMessageBox 
#endif 

Bằng cách xác định lại tên, bạn có thể tránh phân tán rất nhiều điều kiện biên dịch trong suốt mã nguồn của bạn.

+0

Đây là suy nghĩ của tôi về cách thực hiện. Tôi sẽ tránh thay đổi chữ ký chức năng của bạn để làm bài kiểm tra đơn vị. –

-1

Khi có thể, sẽ tốt hơn nếu thực hiện các sự kiện trong khi không sửa đổi các cuộc gọi Win32. Ví dụ: thay vì tạo CreateFile của riêng bạn sẽ thất bại vì tệp đang được sử dụng, thay vào đó, hãy mở tệp bằng chương trình khác (mà bạn gọi từ thử nghiệm đơn vị), sau đó chạy kiểm tra đơn vị.

Nếu bạn phải thử một số cuộc gọi win32, thì tốt nhất bạn nên tạo một thư viện bao quanh các bộ gọi Win32 mà bạn muốn thực hiện. Sau đó, bạn sẽ không làm tổn hại đến việc viết mã của logic chính.

2

Sử dụng Deviare API móc và chặn tất cả cuộc gọi api và thực hiện kiểm tra đơn vị của bạn.

4

Tôi khuyên bạn nên đóng gói các cuộc gọi API vào các giao diện được thừa nhận tốt. Sau đó, bạn có thể kiểm tra logic kinh doanh của bạn bằng cách sử dụng các đối tượng giả hoặc kiểm tra tăng gấp đôi. Bạn không cần phải kiểm tra chính Windows API vì điều này đã được thực hiện bởi hàng triệu ứng dụng Windows đang hoạt động.

Kiểm tra đơn vị sẽ không bao giờ liên quan đến truy cập phần cứng nếu bạn không phát triển phần cứng. Nó chỉ là về kiểm tra mã logic của bạn.

2

Cuối cùng, tôi thực sự đã có thêm một cách tiếp cận C# -ish và các giao diện được tạo ra sẽ cho phép tôi phân tích các cuộc gọi Win32 mà tôi muốn sử dụng.

Ví dụ: tôi có một tên là IRegistryOperations có chứa RegOpenKey, RegQueryValueEx, RegNotifyChange và một số mục khác mà tôi đã sử dụng. Một mặc định mà chỉ đơn giản là các cuộc gọi vào các chức năng thực tế đã được tạo ra trong constructor nhưng tôi cũng đã có một nhà xây dựng đã lấy giao diện để tôi có thể mô phỏng các giá trị tinh ranh, vv

(Không chắc chắn nếu đó là nghi thức xấu để trả lời câu hỏi của riêng tôi)

Các vấn đề liên quan