Is it possible for a PHPUnit test to receive data from separate providers at the same time?

27 views Asked by At

I know I can do this:

/**
 * @dataProvider validInputWithGatewayProvider
 */

public function it_cancels_subscription( string $gateway, array $input ) {
   
   $this
      ->actingAs( $this->createSubscriber() )
      ->withHeaders( [ 'X-Gateway' => $gateway ] )
      ->postJson( $this->route, $input )
      ->assertStatus(200)

}

public function validInputWithGatewayProvider() {
   return [
      [ 
         'paypal' => [ 
            'paypal',
            [ 'subscriptionId' => 'I-XXXX' ]
         ]
      ],
      [
         'stripe' => [ 
            'stripe',
            [ 'subscriptionId' => 'sub_xxxx' ]
         ]
      ],
   ]
}

public function invalidInputWithGatewayProvider() {
   return [
      [ 
         'paypal' => [ 
            'paypal',
            [ 'subscriptionId' => 'invalidId' ]
         ]
      ],
      [
         'stripe' => [ 
            'stripe',
            [ 'subscriptionId' => 'invalidId' ]
         ]
      ],
   ]
}

but I would like to provide the gateway and the input from separate providers, because as you can see in this way I have to add the gateway again in invalidInputWithGatewayProvider for invalid input tests. Ideally, I could do something like this:

/**
 * @dataProvider gatewayProvider
 * @dataProvider validInputProvider
 */

public function it_cancels_subscription( string $gateway, array $input ) {
   
   $this
      ->actingAs( $this->createSubscriber() )
      ->withHeaders( [ 'X-Gateway' => $gateway ] )
      ->postJson( $this->route, $input )
      ->assertStatus(200)

}

public function gatewayProvider() {
   return [
      [ 'paypal' => 'paypal' ],
      [ 'stripe' => 'stripe' ],
   ]
}

public function validInputProvider() {
   return [
      [ 
         'paypal' => [ 'subscriptionId' => 'I-XXXX' ]
      ],
      [
         'stripe' => [ 'subscriptionId' => 'sub_xxxx' ]
      ],
   ]
}

public function invalidInputProvider() {
   return [
      [ 
         [ 'subscriptionId' => 'invalidId' ]
      ]
   ]
}

however the above doesn't do what I'm looking for, because it runs the test once with gatewayProvider, and then again with validInputProvider, so the provided data is always passed to the test as the first parameter.

Of course I can have separate providers and then create a 'middleware' function that merges them into a single provider etc. but I was wondering if there is an easier, built-in solution.

0

There are 0 answers