如何在PHPUnit测试中正确调用WooCommerce购物车函数?
WooCommerce插件单元测试:解决WC()->cart为null的问题
问题背景
我正在开发一款WooCommerce插件,核心功能是限制用户购物车同一时间仅能存在一件商品——用户添加新商品前会自动清空购物车。插件通过woocommerce_add_to_cart_validation过滤器实现,核心代码如下:
/** * Empty cart before add new item * * @param mixed $cart_item_data Cart item data. */ public function woo_custom_add_to_cart_before($cart_item_data) { global $woocommerce; $woocommerce->cart->empty_cart(); return true; }
为验证该功能,我编写了PHPUnit测试代码,但运行时出现错误,测试代码如下:
public function test_only_one_product_in_cart() { activate_plugin('woocommerce/woocommerce.php'); require_once WP_PLUGIN_DIR . '/woocommerce/woocommerce.php'; $product_id = $this->factory->post->create( array( 'post_type' => 'product' ) ); WC()->cart->add_to_cart($product_id); $cart_content = WC()->cart->get_cart_contents_count(); $this->assertEquals(1, $cart_content); }
错误信息
Error: Call to a member function add_to_cart() on null
解决方案
出现该错误是因为WooCommerce购物车对象未初始化,直接调用WC()->cart会返回null。需在测试中正确初始化WooCommerce环境与购物车对象,具体步骤如下:
在setUp方法中完成环境初始化
不要手动加载WooCommerce主文件,而是借助WP测试套件的钩子完成初始化,将环境准备逻辑统一放在setUp方法中:protected function setUp(): void { parent::setUp(); // 激活WooCommerce插件 activate_plugin('woocommerce/woocommerce.php'); // 触发WooCommerce初始化钩子 do_action('woocommerce_init'); // 初始化会话(购物车依赖会话系统) WC()->session->init(); // 实例化购物车对象 WC()->cart = new WC_Cart(); }修正测试逻辑,覆盖核心场景
测试需验证“添加第二个商品时,旧商品被清空,最终仅保留新商品”的核心功能,调整后的测试代码如下:public function test_only_one_product_in_cart() { // 创建两个测试商品 $product1_id = $this->factory->post->create(['post_type' => 'product']); $product2_id = $this->factory->post->create(['post_type' => 'product']); // 添加第一个商品到购物车,验证初始数量 WC()->cart->add_to_cart($product1_id); $this->assertEquals(1, WC()->cart->get_cart_contents_count()); // 触发插件的前置清空逻辑(模拟添加新商品的触发时机) $this->plugin_instance->woo_custom_add_to_cart_before([]); // 添加第二个商品 WC()->cart->add_to_cart($product2_id); // 验证购物车仅保留第二个商品 $this->assertEquals(1, WC()->cart->get_cart_contents_count()); $cart_items = WC()->cart->get_cart(); $this->assertArrayHasKey($product2_id . '::', array_keys($cart_items)); }关键注意事项
- 购物车依赖WooCommerce会话系统,必须先初始化
WC()->session - 避免在测试方法中重复加载WooCommerce,统一在
setUp中处理环境 - 测试需覆盖核心业务场景,而非仅验证单一商品添加
- 购物车依赖WooCommerce会话系统,必须先初始化
内容的提问来源于stack exchange,提问作者Christian Giupponi
相关产品推荐
相关产品推荐

