GTest
[GTest] (2) Example
i5
2025. 1. 9. 01:55
반응형
Below is a more advanced example of two classes, Car and OilBank, that interact with each other. The idea is:
- Car has an internal oil level that can be increased by “refueling” from an OilBank.
- OilBank has a total available capacity of oil and can provide oil to a Car upon request.
You’ll find:
- Car.h / Car.cpp
- OilBank.h / OilBank.cpp
- A sample GTest file (e.g., CarAndOilBankTest.cpp) to test their interaction.
Feel free to adjust the logic to suit your needs!
1. Car.h
#ifndef CAR_H
#define CAR_H
#include <string>
#include "OilBank.h"
class Car {
private:
std::string make;
std::string model;
int year;
double speed;
double oilLevel; // How many liters of oil are currently in the car
double maxOilLevel; // Maximum oil capacity
public:
// Constructor
Car(const std::string& make,
const std::string& model,
int year,
double maxOilLevel = 50.0);
// Basic getters
std::string getMake() const;
std::string getModel() const;
int getYear() const;
double getSpeed() const;
double getOilLevel() const;
double getMaxOilLevel() const;
// Actions
void accelerate(double amount); // Increase speed, consumes some oil
void brake(double amount); // Decrease speed
bool refuel(OilBank& oilBank, double amount); // Request oil from OilBank
};
#endif // CAR_H
2. Car.cpp
#include "Car.h"
#include <algorithm> // for std::max, std::min
Car::Car(const std::string& make,
const std::string& model,
int year,
double maxOilLevel)
: make(make),
model(model),
year(year),
speed(0.0),
oilLevel(0.0),
maxOilLevel(maxOilLevel) {
}
std::string Car::getMake() const {
return make;
}
std::string Car::getModel() const {
return model;
}
int Car::getYear() const {
return year;
}
double Car::getSpeed() const {
return speed;
}
double Car::getOilLevel() const {
return oilLevel;
}
double Car::getMaxOilLevel() const {
return maxOilLevel;
}
void Car::accelerate(double amount) {
if (amount > 0 && oilLevel > 0) {
speed += amount;
// Consumes oil based on how much you accelerate, e.g. 1 liter per 10 units speed
double oilUsed = amount * 0.1;
oilLevel -= oilUsed;
if (oilLevel < 0) {
oilLevel = 0;
}
}
}
void Car::brake(double amount) {
if (amount > 0) {
speed -= amount;
if (speed < 0) {
speed = 0;
}
}
}
bool Car::refuel(OilBank& oilBank, double amount) {
if (amount <= 0) {
return false;
}
// Amount of oil needed to fill the tank up to max
double needed = maxOilLevel - oilLevel;
if (needed <= 0) {
// Already at or above max capacity (though we usually don’t let oilLevel exceed max)
return false;
}
// Only request as much as we can actually fit in the car
double request = (amount > needed) ? needed : amount;
// Request oil from the bank
double provided = oilBank.provideOil(request);
// Increase car’s oilLevel by whatever was provided
oilLevel += provided;
return (provided > 0);
}
3. OliBank.h
#ifndef OILBANK_H
#define OILBANK_H
#include <string>
class OilBank {
private:
std::string name;
double capacity; // Total liters of oil available
public:
// Constructor
OilBank(const std::string& name, double capacity);
// Getters
std::string getName() const;
double getCapacity() const;
// Provide oil to a Car
// Returns the actual amount of oil provided.
double provideOil(double requestedAmount);
};
#endif // OILBANK_H
4. OliBank.cpp
#include "OilBank.h"
#include <algorithm> // for std::min
OilBank::OilBank(const std::string& name, double capacity)
: name(name), capacity(capacity) {
}
std::string OilBank::getName() const {
return name;
}
double OilBank::getCapacity() const {
return capacity;
}
double OilBank::provideOil(double requestedAmount) {
if (requestedAmount <= 0) {
return 0.0;
}
// The actual amount we can provide is limited by our current capacity
double provided = std::min(capacity, requestedAmount);
// Deduct from capacity
capacity -= provided;
return provided;
}
5. CarAndOilBankTest.cpp (GTest)
#include <gtest/gtest.h>
#include "Car.h"
#include "OilBank.h"
// 1. Test the OilBank alone
TEST(OilBankTest, ConstructionAndProvideOil) {
OilBank bank("Global Oil", 100.0);
EXPECT_EQ(bank.getName(), "Global Oil");
EXPECT_DOUBLE_EQ(bank.getCapacity(), 100.0);
// Request 50 liters
double provided = bank.provideOil(50.0);
EXPECT_DOUBLE_EQ(provided, 50.0);
EXPECT_DOUBLE_EQ(bank.getCapacity(), 50.0);
// Request more than remaining
provided = bank.provideOil(60.0);
EXPECT_DOUBLE_EQ(provided, 50.0); // only 50 left
EXPECT_DOUBLE_EQ(bank.getCapacity(), 0.0);
// Bank is now empty
provided = bank.provideOil(10.0);
EXPECT_DOUBLE_EQ(provided, 0.0);
EXPECT_DOUBLE_EQ(bank.getCapacity(), 0.0);
}
// 2. Test Car's basic features
TEST(CarTest, BasicProperties) {
Car car("Toyota", "Camry", 2022, 60.0);
EXPECT_EQ(car.getMake(), "Toyota");
EXPECT_EQ(car.getModel(), "Camry");
EXPECT_EQ(car.getYear(), 2022);
EXPECT_DOUBLE_EQ(car.getSpeed(), 0.0);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 0.0);
EXPECT_DOUBLE_EQ(car.getMaxOilLevel(), 60.0);
}
TEST(CarTest, AccelerateAndBrake) {
Car car("Honda", "Civic", 2023, 50.0);
// No oil => accelerate should not increase speed
car.accelerate(10.0);
EXPECT_DOUBLE_EQ(car.getSpeed(), 0.0);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 0.0);
// Let's manually set some oil (for demonstration or we can refuel from an OilBank)
// For real usage, you'd want to test refuel logic. Here we do a shortcut:
// Typically you'd keep oil private, so consider adding a 'fillOilForTest' if you want
// to manipulate it in tests. But let's do the official approach: create an OilBank and refuel.
}
// 3. Test Car refueling from OilBank
TEST(CarAndOilBankInteractionTest, Refuel) {
Car car("BMW", "i8", 2021, 40.0);
OilBank bank("Premium Oil", 100.0);
// Initially, car has 0 oil
EXPECT_DOUBLE_EQ(car.getOilLevel(), 0.0);
// Refuel 20 liters
bool success = car.refuel(bank, 20.0);
EXPECT_TRUE(success);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 20.0);
EXPECT_DOUBLE_EQ(bank.getCapacity(), 80.0); // 100 - 20
// Try refueling another 30 liters (car only needs 20 more to max at 40)
success = car.refuel(bank, 30.0);
EXPECT_TRUE(success);
// Car's max is 40, so it should now be at 40
EXPECT_DOUBLE_EQ(car.getOilLevel(), 40.0);
// The bank provided only 20 (not 30) because the car needed 20
EXPECT_DOUBLE_EQ(bank.getCapacity(), 60.0);
// Car is at max oil; requesting more should fail or do nothing
success = car.refuel(bank, 10.0);
EXPECT_FALSE(success);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 40.0);
EXPECT_DOUBLE_EQ(bank.getCapacity(), 60.0);
}
// 4. Test that accelerating consumes oil
TEST(CarAndOilBankInteractionTest, AccelerateConsumesOil) {
Car car("Tesla", "Model S", 2024, 50.0);
OilBank bank("ElectricOil?", 20.0);
// Refuel 15 liters
car.refuel(bank, 15.0);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 15.0);
EXPECT_DOUBLE_EQ(bank.getCapacity(), 5.0);
// Accelerate by 10 => speed goes to 10 if there's enough oil
car.accelerate(10.0);
EXPECT_DOUBLE_EQ(car.getSpeed(), 10.0);
// Consumes 1 liter (10 * 0.1 = 1)
EXPECT_DOUBLE_EQ(car.getOilLevel(), 14.0);
// Accelerate by 140 => tries to use 14 liters of oil
car.accelerate(140.0);
// Car had 14 liters left => enough to accelerate fully
// speed => 10 + 140 = 150
// oil => 14 - (140 * 0.1) = 0
EXPECT_DOUBLE_EQ(car.getSpeed(), 150.0);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 0.0);
// No oil => further acceleration does nothing
car.accelerate(50.0);
EXPECT_DOUBLE_EQ(car.getSpeed(), 150.0);
EXPECT_DOUBLE_EQ(car.getOilLevel(), 0.0);
}
// 5. Test that braking never goes below 0
TEST(CarTest, BrakeNeverNegative) {
Car car("Test", "Braker", 2020, 10.0);
// Force a non-zero speed (ignore oil for now, or imagine we did have some oil)
// In real tests, you'd want to handle it properly, but let's pretend:
car.accelerate(10.0);
// This won't actually accelerate if there's no oil, so let's do one more trick:
OilBank dummyBank("Dummy", 100.0);
car.refuel(dummyBank, 10.0);
car.accelerate(10.0);
EXPECT_GT(car.getSpeed(), 0.0);
// Now test braking
car.brake(5.0);
EXPECT_DOUBLE_EQ(car.getSpeed(), 5.0);
// Over-brake => speed goes to 0, not negative
car.brake(999.0);
EXPECT_DOUBLE_EQ(car.getSpeed(), 0.0);
}
반응형