集成测试与单元测试适用场景疑问:两类代码场景该如何选择测试类型
单元测试与集成测试场景选择解答
场景1:线程创建活动记录测试
结论:你当前写的测试属于集成测试,符合「不发起HTTP请求」的要求
单元测试的核心是仅测试单一代码单元的逻辑,完全隔离所有外部依赖。你现在实现的测试逻辑:
- 调用Thread工厂触发创建事件,联动Observer执行
- 直接查询数据库校验activities表是否有对应记录
已经覆盖了Observer触发、Activity记录类处理、数据库写入三个独立模块的联动验证,属于典型的集成测试。你可以使用内存数据库跑这个测试,全程不会发起HTTP请求,完全满足要求。
如果你想写对应单元测试,需要单独实例化ThreadObserver,mock掉Activity类和event事件调度器,只验证created方法内是否调用了对应的依赖方法即可,不需要操作数据库。
// 场景1相关代码 class ThreadObserver extends Observer { public function created(Thread $thread) { Activity::record($thread); event(new ThreadWasCreated($thread)); } } class RecordsActivityTest { public function it_records_the_activity_when_a_thread_is_created() { Thread::factory()->create(); $this->assertDatabaseHas('activities', […]); } }
场景2:依赖Index类的Search类测试
结论:两种测试类型都可以,取决于你的测试目标
- 如果你要验证的是Search类自身的逻辑正确性,不需要依赖Index类的真实实现,那就写单元测试:给Index类创建mock/stub,固定
$index->search()的返回值,只校验Search类handle方法中的自有处理逻辑是否符合预期即可。 - 如果你要验证的是Search类和Index类联动后的查询结果正确性,那就写集成测试,直接传入真实的Index实例,跑完整查询逻辑校验返回结果。你现在写的测试用例直接实例化了真实的Index类,属于集成测试的写法。
// 场景2相关代码 class Search { public function __construct(protected Index $index) { } public function handle($query) { $this->index->search($query); // more code } } class SearchTest { public function it_returns_the_expected_result() { $search = new Search(new Index); $results = $search->handle("some query"); $this->assertEquals("some Data", $results); } }
内容的提问来源于stack exchange,提问作者Orestis uRic
相关产品推荐
相关产品推荐

