๊ฐœ๋… ์†Œ๊ฐœ

Laravel Testing์—์„œ Mock ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ๋•Œ โ€˜overload:โ€˜์™€ โ€˜alias:โ€˜๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ค‘์š”ํ•œ ํŒจํ„ด์ด๋‹ค.

Mock ํƒ€์ž…๋ณ„ ํŠน์ง•

overload: ํŒจํ„ด

์ƒˆ๋กœ์šด ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ๊ฐ€๋กœ์ฑ„์„œ Mock ๊ฐ์ฒด๋กœ ๋Œ€์ฒดํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ฃผ์š” ํŠน์ง•

  • new ํ‚ค์›Œ๋“œ๋กœ ์ƒ์„ฑ๋˜๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€๋กœ์ฑ”
  • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์‚ฌ์šฉ
  • ์˜์กด์„ฑ ์ฃผ์ž…์ด ์–ด๋ ค์šด ์ƒํ™ฉ์—์„œ ์œ ์šฉ
class OrderProcessor {
    public function process()
    {
        $paymentGateway = new PaymentGateway();
        return $paymentGateway->charge();
    }
}
 
class OrderProcessorTest extends TestCase
{
    public function testProcessOrder()
    {
        // PaymentGateway ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ๊ฐ€๋กœ์ฑ”
        $mock = Mockery::mock('overload:PaymentGateway');
        $mock->shouldReceive('charge')
             ->once()
             ->andReturn(true);
 
        $processor = new OrderProcessor();
        $result = $processor->process();
 
        $this->assertTrue($result);
    }
}

alias: ํŒจํ„ด

์ •์ (static) ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ Mock ๊ฐ์ฒด๋กœ ๋Œ€์ฒดํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ฃผ์š” ํŠน์ง•

  • ํด๋ž˜์Šค์˜ static ๋ฉ”์„œ๋“œ๋ฅผ ๋Œ€์ฒด
  • ํŒŒ์‚ฌ๋“œ(Facade) ํŒจํ„ด์ด๋‚˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ํ…Œ์ŠคํŠธํ•  ๋•Œ ์‚ฌ์šฉ
  • ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ ํ…Œ์ŠคํŠธ์— ์œ ์šฉ
class NotificationService {
    public function send()
    {
        return Logger::log('Notification sent');
    }
}
 
class NotificationServiceTest extends TestCase
{
    public function testSendNotification()
    {
        // Logger์˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ Mock์œผ๋กœ ๋Œ€์ฒด
        $mock = Mockery::mock('alias:Logger');
        $mock->shouldReceive('log')
             ->with('Notification sent')
             ->once()
             ->andReturn(true);
 
        $service = new NotificationService();
        $result = $service->send();
 
        $this->assertTrue($result);
    }
}

์‹ค์ œ ํ™œ์šฉ ์‚ฌ๋ก€

overload: ํ™œ์šฉ ์˜ˆ์‹œ

class UserRepository {
    public function create($data)
    {
        $validator = new DataValidator();
        if ($validator->validate($data)) {
            return User::create($data);
        }
        return false;
    }
}
 
class UserRepositoryTest extends TestCase
{
    public function testCreateUser()
    {
        // DataValidator ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์„ ๊ฐ€๋กœ์ฑ”
        $validatorMock = Mockery::mock('overload:DataValidator');
        $validatorMock->shouldReceive('validate')
                     ->once()
                     ->andReturn(true);
 
        $repo = new UserRepository();
        $result = $repo->create(['name' => 'Test User']);
        
        $this->assertInstanceOf(User::class, $result);
    }
}

alias: ํ™œ์šฉ ์˜ˆ์‹œ

class EmailService {
    public function sendWelcomeEmail($user)
    {
        if (Config::get('mail.enabled')) {
            return Mailer::send('welcome', ['user' => $user]);
        }
        return false;
    }
}
 
class EmailServiceTest extends TestCase
{
    public function testSendWelcomeEmail()
    {
        // Config์™€ Mailer์˜ ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ Mock์œผ๋กœ ๋Œ€์ฒด
        $configMock = Mockery::mock('alias:Config');
        $configMock->shouldReceive('get')
                  ->with('mail.enabled')
                  ->andReturn(true);
 
        $mailerMock = Mockery::mock('alias:Mailer');
        $mailerMock->shouldReceive('send')
                  ->once()
                  ->andReturn(true);
 
        $service = new EmailService();
        $result = $service->sendWelcomeEmail(['name' => 'Test User']);
        
        $this->assertTrue($result);
    }
}

์‚ฌ์šฉ ์‹œ ์ฃผ์˜์‚ฌํ•ญ

overload: ์ฃผ์˜์‚ฌํ•ญ

  • ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์ค‘ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ์— ์˜ํ–ฅ
  • ํ•œ ๋ฒˆ overload๋œ ํด๋ž˜์Šค๋Š” ํ•ด๋‹น ํ…Œ์ŠคํŠธ ์‹คํ–‰ ๋™์•ˆ ๊ณ„์† ์ ์šฉ
  • ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ tearDown์—์„œ ์ •๋ฆฌ ํ•„์š”

alias: ์ฃผ์˜์‚ฌํ•ญ

  • ์ •์  ๋ฉ”์„œ๋“œ๋งŒ mock ๊ฐ€๋Šฅ
  • ์ผ๋ฐ˜ ์ธ์Šคํ„ด์Šค ๋ฉ”์„œ๋“œ๋Š” ์˜ํ–ฅ๋ฐ›์ง€ ์•Š์Œ
  • ์ „์—ญ์ ์œผ๋กœ ์ ์šฉ๋˜๋ฏ€๋กœ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์™€์˜ ๊ฒฉ๋ฆฌ ์ฃผ์˜

์„ ํƒ ๊ฐ€์ด๋“œ

overload: ์‚ฌ์šฉ ์‹œ๊ธฐ

  • new ํ‚ค์›Œ๋“œ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•ด์•ผ ํ•  ๋•Œ
  • ์˜์กด์„ฑ ์ฃผ์ž…์ด ์–ด๋ ค์šด ๋ ˆ๊ฑฐ์‹œ ์ฝ”๋“œ ํ…Œ์ŠคํŠธ
  • ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ๊ณผ์ •์„ ์ œ์–ดํ•ด์•ผ ํ•  ๋•Œ

alias: ์‚ฌ์šฉ ์‹œ๊ธฐ

  • ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ ํ…Œ์ŠคํŠธ
  • Laravel Facade ํŒจํ„ด ํ…Œ์ŠคํŠธ
  • ์ „์—ญ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜ ํ…Œ์ŠคํŠธ

์„ฑ๋Šฅ ๊ณ ๋ ค์‚ฌํ•ญ

overload:

  • ํด๋ž˜์Šค ๋กœ๋” ์ˆ˜์ค€์—์„œ ๋™์ž‘ํ•˜๋ฏ€๋กœ ์•ฝ๊ฐ„์˜ ์„ฑ๋Šฅ ์˜ํ–ฅ
  • ๋งŽ์€ ์ˆ˜์˜ overload๋ฅผ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ํ…Œ์ŠคํŠธ ์‹คํ–‰ ์†๋„ ์ €ํ•˜ ๊ฐ€๋Šฅ

alias:

  • ์ •์  ํ˜ธ์ถœ๋งŒ ์˜ํ–ฅ๋ฐ›์œผ๋ฏ€๋กœ ์ƒ๋Œ€์ ์œผ๋กœ ๊ฐ€๋ฒผ์›€
  • ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ ์Œ

๊ฒฐ๋ก 

Laravel ํ…Œ์ŠคํŠธ์—์„œ โ€˜overload:โ€˜์™€ โ€˜alias:โ€˜๋Š” ๊ฐ๊ฐ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๊ณผ ์ •์  ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ Mockํ•˜๋Š” ๋ฐ ํŠนํ™”๋œ ํŒจํ„ด์ด๋‹ค. ํ…Œ์ŠคํŠธ ๋Œ€์ƒ ์ฝ”๋“œ์˜ ํŠน์„ฑ๊ณผ ์˜์กด์„ฑ ํŒจํ„ด์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ๋ฐฉ์‹์„ ์„ ํƒํ•ด์•ผ ํ•œ๋‹ค.