Tôi đang cố gắng thực hiện thử nghiệm đơn vị với googlemock và tiêm phụ thuộc trong C++. Mocks và phụ thuộc tiêm đáng kể dễ dàng kiểm tra mã, nhưng họ rất nhiều dựa vào phương pháp ảo. Mặc dù các lớp trong các ngôn ngữ khác sử dụng các phương thức ảo theo mặc định, nó không phải là trường hợp của C++. Tôi đang sử dụng C++ để tạo ra một khuôn khổ đo lường hiệu suất thấp, vì vậy chỉ cần làm cho mọi lớp đơn thừa kế từ một giao diện (w/các phương thức ảo thuần túy) không phải là một tùy chọn mong muốn.Phun và phụ thuộc vào C++
Cụ thể, tôi đang gặp vấn đề với các lớp học thử nghiệm có chứa bộ sưu tập của các đối tượng như một sau:
struct event_info { /* ... */ };
template<typename Event>
class event_manager {
public:
event_manager(const std::vector<event_info>& events) {
std::transform(begin(events), end(events),
std::back_inserter(events_),
[](const event_info& info) { return Event{info}; });
}
void read() {
for (auto& e : events_)
e.read();
}
// ...
private:
std::vector<Event> events_;
// ...
};
Để kiểm tra lớp này tôi có thể làm như sau:
class mock_event {
public:
MOCK_METHOD0(read, void());
};
TEST(event_manager, test) {
event_manager<mock_event> manager;
// ...
}
Nhưng điều này sẽ không hoạt động vì tôi không thể đặt kỳ vọng cho đối tượng giả và đối tượng giả từ googlemock không thể sao chép được (do đó, lệnh gọi tới std::transform
không thể biên dịch được).
Để giải quyết vấn đề này, khi thử nghiệm, tôi có thể sử dụng con trỏ thay thế (ví dụ: event_manager<mock_event*>
) và chuyển nhà máy đến nhà xây dựng event_manager
. Tuy nhiên, điều này sẽ không biên dịch vì các cuộc gọi như e.read()
(nó phải là e->read()
thay vì khi thử nghiệm).
Sau đó, tôi có thể sử dụng các đặc điểm kiểu để tạo phương thức nếu đưa ra tham chiếu vừa trả về tham chiếu và nếu có con trỏ, thì hãy chọn con trỏ (ví dụ: dereference(e).read()
). Tuy nhiên, điều này chỉ tiếp tục thêm tấn phức tạp và nó không giống như một giải pháp tốt (đặc biệt là nếu cần phải được thực hiện để kiểm tra tất cả các lớp có chứa một bộ sưu tập các đối tượng).
Vì vậy, tôi đã tự hỏi liệu có một giải pháp tốt hơn cho điều này, hoặc nó chỉ là chế nhạo và phụ thuộc tiêm không phải là kỹ thuật rất thích hợp cho C + +.
Đây là một câu hỏi hay! Tôi mong chờ câu trả lời. Trong sự hiểu biết của tôi, có lẽ bạn có thể cố gắng sửa đổi 'event_manager' một chút, sử dụng' std :: vector> ', có lẽ điều này giải quyết được vấn đề. Nhưng tôi đã không cố gắng để không chắc chắn nếu nó hoạt động. –
Mine
@Mine Sử dụng 'unique_ptr' và một nhà máy (hoặc chỉ thay đổi giao diện cho phép người dùng thêm' unique_ptr ') sẽ hoạt động. Nhưng sau đó tôi cần phải lưu trữ con trỏ trong sản xuất quá (không chỉ trong khi thử nghiệm), và tôi đang tìm một giải pháp để tránh điều đó. –
betabandido
Yup, tôi có nghĩa là bạn có thể lưu trữ con trỏ ('unique_ptr') bot cả mã sản xuất và mã thử nghiệm. Đó không phải là một vấn đề. – Mine