I have a simple Entity consisting of just one field "name":
/**
* @ORM\Table(name="gender")
* @ORM\Entity
* @codeCoverageIgnore
*/
class Gender
{
public const FEMALE = 'female';
public const MALE = 'male';
public const OTHER = 'other';
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=15, nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private string $name;
public function getName(): string
{
return $this->name;
}
public function setName(string $name): Gender
{
$this->name = $name;
return $this;
}
}
For this class I try to generate fixtures and insert them into a sqlite db for testing:
use App\Entity\Gender; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager;
class GenderFixtures extends Fixture
{
public function load(ObjectManager $manager)
{
$genders = [Gender::FEMALE, Gender::MALE, Gender::OTHER];
foreach ($genders as $genderName) {
echo $genderName . PHP_EOL;
$gender = (new Gender())
->setName($genderName);
$manager->persist($gender);
}
$manager->flush();
}
}
When I call
bin/console doctrine:fixtures:load --env=test
I get this:
female
male
other
In AbstractSQLiteDriver.php line 39:
An exception occurred while executing 'INSERT INTO gender (name) VALUES (null)':
SQLSTATE[23000]: Integrity constraint violation: 19 NOT NULL constraint failed: gender.name
So as you can see there are the three strings I want to use as name. Why are they not used by the Fixture in the insert statement?
Symfony 4.4, PHP 7.4.1, Doctrine Fixtures 3.3.0
It seems like fixtures filling a sqlite db cannot deal with primary keys, which are not auto incremented integers.
The same fixtures worked on a MySql database like a charm. So as long as I want to use the sqlite db for unittests, I added to all my entities
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="smallint", options={"unsigned":true})
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private ?int $id = null;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=15, nullable=false)
*/
private string $name;
And of course I had to change the naming and the referenced column for the connected entities.
Still I don't know if it is wise to use a different db for testing than for dev and prod. Problems like this show that it is not an ideal solution.
When I did run a similar application locally, I just had another MySql db for testing. Now I run this app in docker and had troubles in using a different db for tests, than for dev. Hence the sqlite solution....