"매 linker 의 symbol resolution 을 test 의 enabling point 로 활용". Michael Feathers, Working Effectively with Legacy Code (2004) — 매 source code 변경 없이 link-time 의 symbol substitution 으로 dependency 를 break 하는 seam. C/C++ 의 native 기법, 2026 에서는 매 dynamic library injection (LD_PRELOAD), test double linking, 또는 Bazel/CMake test target 분리 로 활용.
매 핵심
매 Feathers 의 3 seam types
Preprocessing seam: #define, #ifdef 의 compile-time substitution.
Link seam: linker 의 symbol resolution 의 test/prod binary 분리.
Object seam: virtual function / interface 의 polymorphic dispatch.
매 Link seam 의 enabling mechanism
매 production code 와 test code 가 동일 header / function signature 를 share.
매 production binary 는 real implementation .o link.
매 test binary 는 fake/stub implementation .o link.
매 source 파일 변경 없이 매 dependency 의 substitute.
매 응용
C/C++ legacy code 의 testability 도입 (most classic use case).
System call wrapping (LD_PRELOAD 의 fake gettimeofday).
Hardware abstraction layer (HAL) 의 test build.
Mock library injection (e.g., FFF in C, googlemock 의 link-time mock).
Embedded system unit testing on host.
💻 패턴
1. C link seam (canonical)
// time_provider.h
#ifndef TIME_PROVIDER_H
#define TIME_PROVIDER_H
longcurrent_time_ms(void);#endif
// production: time_provider_real.c
#include<time.h>longcurrent_time_ms(void){structtimespects;clock_gettime(CLOCK_MONOTONIC,&ts);returnts.tv_sec*1000+ts.tv_nsec/1000000;}// test: time_provider_fake.c
staticlongfake_now=0;longcurrent_time_ms(void){returnfake_now;}voidset_fake_time(longt){fake_now=t;}// Production link
// gcc app.c time_provider_real.c -o app
// Test link
// gcc test_app.c time_provider_fake.c -o test_app
// production_default.c
__attribute__((weak))intsensor_read(void){returnread_real_sensor();}// test_override.c
intsensor_read(void){return42;// strong symbol overrides weak
}// Test build links test_override.c → uses fake.
// Prod build doesn't link test_override.c → uses weak default.
6. FFF (Fake Function Framework, C)
#include"fff.h"DEFINE_FFF_GLOBALS;// Header declares: void send_packet(const char* data);
FAKE_VOID_FUNC(send_packet,constchar*);voidtest_send(void){RESET_FAKE(send_packet);do_thing();assert(send_packet_fake.call_count==1);}// Link test binary with fakes instead of real send_packet.
7. Migration to object seam (preferred long-term)
// 매 link seam 은 stepping stone
// 매 long-term: interface + DI 로 evolve
classTimeProvider{public:virtuallongnow_ms()=0;virtual~TimeProvider()=default;};classRealTimeProvider:publicTimeProvider{longnow_ms()override{/* real */}};classFakeTimeProvider:publicTimeProvider{public:longfake_now=0;longnow_ms()override{returnfake_now;}};// Now no link tricks needed — just inject.
매 결정 기준
상황
Approach
Legacy C code, 매 interface 도입 어려움
Link seam.
C++ codebase, 매 refactor 가능
Object seam (virtual / interface).
System call / library function 의 mocking
LD_PRELOAD link seam.
Embedded HAL의 host testing
Link seam (fake HAL implementation).
Modern code, full DI
Object seam — link seam 불필요.
Single-binary monolith 의 sub-module test
Link seam 또는 build target 분리.
기본값: 새 C/C++ 코드는 매 object seam 으로 시작. Link seam 은 매 legacy 의 testability rescue tool.
언제: legacy C/C++ codebase 의 unit test 도입, system call mocking, embedded HAL host test.
언제 X: 매 modern dynamic language (Python/JS/Ruby — monkey patch 충분), 매 fresh codebase (object seam 이 cleaner).
❌ 안티패턴
Production binary 에 test fake 누설: 매 build target separation 실패 시 매 prod 가 fake link. 매 strict CMake/Bazel target 분리.
Symbol collision: 매 multiple translation unit 에서 동일 symbol — undefined behavior.
LD_PRELOAD 의 prod 사용: 매 debugging 도구로만, 매 production deploy 의 anti-pattern.
Header/source mismatch: 매 fake 가 매 signature 변경 의 stale — 매 ABI mismatch crash.
Link seam 의 영구화: 매 stepping stone, 매 object seam 으로 evolve 의 missing.
🧪 검증 / 중복
Verified (Feathers, Working Effectively with Legacy Code 2004, Ch.4 "The Seam Model").
신뢰도 A.
🕓 Changelog
날짜
변경
2026-05-08
Phase 1
2026-05-10
Manual cleanup — Feathers seam taxonomy + CMake/Bazel/LD_PRELOAD modern application