Let's talk about how to fake time in a test. What do I mean by that?
What if you want to test the situation that would happen in the future or should have occurred in the past depending on some, for example, database field like published_at
or created_at
?
You can set the "fake" time to run a specific test method.
Scenario Example
For example, you have published_at
in the database table and want to show only published records on your home page.
Schema::table('products', function (Blueprint $table) { $table->dateTime('published_at')->nullable()->after('price');});
Then, in the Model, you have an optional scope of published
.
use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Builder; class Product extends Model{ use HasFactory; protected $fillable = [ 'name', 'price', 'published_at', ]; public function scopePublished(Builder $query): Builder { return $query->whereNotNull('published_at') ->where('published_at', '<=', now()); }}
And, in the Controller, you get only the published records.
use App\Models\Product;use Illuminate\View\View; class ProductController extends Controller{ public function index(): View { $products = Product::published()->get(); return view('products.index', compact('products')); } // ...}
The Test
Then, in the test, you create...