PhpUnit giving errror at second test function - testing

I am trying to make test to my Database with phpunit and I migrate the database to memory.
the first test run just fine:
/** #test */
public function it_fetches_a_single_ano_letivo()
{
$this->makeAnoLetivo();
$this->getJson('/v1/anos-letivos');
$this->assertResponseOk();
}
but the second test fails and its exactly the same as the first one:
/** #test */
public function it_fetches_anos_letivos()
{
$this->makeAnoLetivo();
$this->getJson('/v1/anos-letivos');
$this->assertResponseOk();
}
Here is the makeAnoLetivo function:
private function makeAnoLetivo($anoLetivoFields = [])
{
while($this->times--)
{
$ano1=$this->fake->year;
$anoLetivo = array_merge([
'ano1' => $ano1+0,
'ano2' => $ano1+1
], $anoLetivoFields);
AnoLetivo::create($anoLetivo);
}
}
and here is the phpUnit output:
Configuration read from {{PATH_TO_PROJECT}}/phpunit.xml
..E
Time: 2.62 seconds, Memory: 23.25Mb
There was 1 error:
1) AnosLetivosTest::it_fetches_anos_letivos
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 anos_letivos.id may not be NULL (SQL: insert into "anos_letivos" ("ano1", "ano2", "updated_at", "created_at") values (2009, 2010, 2015-03-27 18:41:59, 2015-03-27 18:41:59))
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:620
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:576
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:359
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:316
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1702
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:933
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1603
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1603
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1501
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:544
{{PATH_TO_PROJECT}}/tests/AnosLetivosTest.php:50
{{PATH_TO_PROJECT}}/tests/AnosLetivosTest.php:32
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:152
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:104
Caused by
PDOException: SQLSTATE[23000]: Integrity constraint violation: 19 anos_letivos.id may not be NULL
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:358
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:612
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:576
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:359
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Connection.php:316
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:1702
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:933
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1603
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1603
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1501
{{PATH_TO_PROJECT}}/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:544
{{PATH_TO_PROJECT}}/tests/AnosLetivosTest.php:50
{{PATH_TO_PROJECT}}/tests/AnosLetivosTest.php:32
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:152
phar:///usr/local/bin/phpunit/phpunit/TextUI/Command.php:104
FAILURES!
Tests: 3, Assertions: 5, Errors: 1.
So the first function run just fine but the second one is the same and fails...
Also if i create a third one (equal) only the first one will pass.
EDIT 1:
So it inserts well in the first test, it rollbacks the DB and Migrates it again for the next test and the insert in the database says the ID may not be NULL, so it seems the create method no longer knows how to insert in the database after the first test... still dont know what causes this, the migrate is correct and it is rollback"ing" well too...
Edit 2:
I tried to run the tests against the production database and it works just fine. So the problem must be on the memory database or on any configuration on this memory database. But I dont know what problem because the first test I get green and it inserts the data without problems, i can even insert 10 items in the first test and it does what it should. But the second test shows the error above.

It looks like the database insert command is failing after the first test. Could be for a number of reasons.
I think you should consider using https://github.com/laracasts/TestDummy - it is designed to allow you to have fake data for all your tests. It will also automatically reset your database between each test (using transactions).
Its a wonderful tool - give it a go

So the solution was to write this lines on the setUp() method:
AnoLetivo::flushEventListeners();
AnoLetivo::boot();
the problem may be in the laravel framework.

Related

How to reset the auto incremented id column to 1 whenever I seed the database in postgreSQL?

I am using Supabase as a backend which provides postgres as its database and prisma for my next-js app. I wanted to seed some dummy data into the database. The first time I run the seed script, everything's fine but when I ran the script multiple times, even though I deleted all rows before seeding, the primary id (which auto increments by default) of the table is not resetting to 1. Instead, it is incrementing from the previous value. I tried something like this:
await prisma.user.deleteMany();
await prisma.post.deleteMany();
await prisma.$queryRaw`ALTER SEQUENCE user_id_seq RESTART WITH 1`;
await prisma.$queryRaw`ALTER SEQUENCE post_id_seq RESTART WITH 1`;
This is error occurred when I run raw SQL code in prisma:
PrismaClientKnownRequestError:
Invalid `prisma.$queryRaw()` invocation:
Raw query failed. Code: `42P01`. Message: `relation "user_id_seq" does not exist`
at RequestHandler.handleRequestError (/home/surya/projects/social-media-demo/node_modules/#prisma/client/runtime/index.js:29909:13)
at RequestHandler.request (/home/surya/projects/social-media-demo/node_modules/#prisma/client/runtime/index.js:29892:12)
at async Proxy._request (/home/surya/projects/social-media-demo/node_modules/#prisma/client/runtime/index.js:30864:16) {
code: 'P2010',
clientVersion: '4.3.1',
meta: { code: '42P01', message: 'relation "user_id_seq" does not exist' }
}
Is deleting all the tables and running migrations again as a fresh start the only way?
Try it like this, it will delete the data and restart the sequence:
TRUNCATE TABLE <tableName> RESTART IDENTITY;

Static Hangfire RecurringJob methods in LINQPad are not behaving

I have a script in LINQPad that looks like this:
var serverMode = EnvironmentType.EWPROD;
var jobToSchedule = JobType.ABC;
var hangfireCs = GetConnectionString(serverMode);
JobStorage.Current = new SqlServerStorage(hangfireCs);
Action<string, string, XElement> createOrReplaceJob =
(jobName, cronExpression, inputPackage) =>
{
RecurringJob.RemoveIfExists(jobName);
RecurringJob.AddOrUpdate(
jobName,
() => new BTR.Evolution.Hangfire.Schedulers.JobInvoker().Invoke(
jobName,
inputPackage,
null,
JobCancellationToken.Null),
cronExpression, TimeZoneInfo.Local);
};
// psuedo code to prepare inputPackage for client ABC...
createOrReplaceJob("ABC.CustomReport.SurveyResults", "0 2 * * *", inputPackage);
JobStorage.Current.GetConnection().GetRecurringJobs().Where( j => j.Id.StartsWith( jobToSchedule.ToString() ) ).Dump( "Scheduled Jobs" );
I have to schedule in both QA and PROD. To do that, I toggle the serverMode variable and run it once for EWPROD and once for EWQA. This all worked fine until recently, and I don't know exactly when it changed unfortunately because I don't always have to run in both environments.
I did purchase/install LINQPad 7 two days ago to look at some C# 10 features and I'm not sure if that affected it.
But here is the problem/flow:
Run it for EWQA and everything works.
Run it for EWPROD and the script (Hangfire components) seem to run in a mix of QA and PROD.
When I'm running it the 'second time' in EWPROD I've confirmed:
The hangfireCs (connection string) is right (pointing to PROD) and it is assigned to JobStorage.Current
The query at the end of the script, JobStorage.Current.GetConnection().GetRecurringJobs() uses the right connection.
The RecurringJob.* methods inside the createOrReplaceJob Action use the connection from the previous run (i.e. EWQA). If I monitor my QA Hangfire db, I see the job removed and added.
Temporary workaround:
Run it for EWQA and everything works.
Restart LINQPad or use 'Cancel and Reset All Queries' method
Run it for EWPROD and now everything works.
So I'm at a loss of where the issue might lie. I feel like my upgrade/install of LINQPad7 might be causing problems, but I'm not sure if there is a different way to make the RecurringJob.* static methods use the 'updated' connection string.
Any ideas on why the restart or reset is now needed?
LINQPad - 5.44.02
Hangfire.Core - 1.7.17
Hangfire.SqlServer - 1.7.17
This is caused by your script (or a library that you call) caching something statically, and not cleaning up between executions.
Either clear/dispose objects when you're done (e.g., JobStorage.Current?) or tell LINQPad not to re-use the process between executions, by adding Util.NewProcess=true; to your script.

Table not found in Production - Laravel

I have what people say "it works on my computer" issue.
On my Trait, I have the following code:
use App\Models\Lessons;
...
$lessons = Lessons::find($lesson);
But when I fire this up in production, it gives error message Base table or view not found: 1146 Table db.Lessons doesn't exist (SQL: select * from LessonswhereLessons.id = 5 limit 1) ....
I check my model and I can find protected $table = 'Lessons';. (This was the #1 SO answer given based on the related question)
I also checked the DB and I can see the lessons table.
BTW, this works in local.
I have tried deleting the DB, and rerunning artisan/seeder/etc (This a new install so no problem dropping) but still getting the same issue. Any opinions are highly appreciated.

DoubleClick Offline Conversion API Deleting on duplicate records?

Trying to use the DoubleClick API with the Google Client PHP SDK described here https://developers.google.com/doubleclick-advertisers/v3.1/conversions/batchupdate
I'm finding that instead of an update happening, these conversions are being removed from our reports. I suspect something with De-duplication, but I wouldn't expect that the conversion be completely removed.
I'm basically doing this:
$conversion = new Google_Service_Dfareporting_Conversion();
$conversion->setKind("dfareporting#conversion");
$conversion->setGclid($clickId);
$conversion->setFloodlightActivityId($this->getActivityId());
$conversion->setFloodlightConfigurationId($this->getConfigId());
$conversion->setOrdinal($conversionId);
$conversion->setTimestampMicros($conversionTimestamp);
$conversion->setQuantity(1);
$conversion->setValue($revenue);
$doubleClickSearch = new Google_Service_Dfareporting($this->getGoogleApiClient());
$conversionList = new Google_Service_Dfareporting_ConversionsBatchUpdateRequest();
$conversionList->setKind("dfareporting#conversionsBatchUpdateRequest");
$conversionList->setConversions([$conversion]);
return $doubleClickSearch->conversions->batchupdate($this->getUserProfileId(), $conversionList);
And when this gets run, it works as expected:
{"hasFailures":false,
"kind":"dfareporting#conversionsBatchUpdateResponse",
"status":[
{"kind":"dfareporting#conversionStatus",
"conversion":{
"childDirectedTreatment":null,
"encryptedUserId":null,
"encryptedUserIdCandidates":null,
"floodlightActivityId":"redacted",
"floodlightConfigurationId":"redacted",
"gclid":"redacted",
"kind":"dfareporting#conversion",
"limitAdTracking":null,
"mobileDeviceId":null,
"ordinal":"redactedConversionId",
"quantity":"1",
"timestampMicros":"1532697843000000",
"value":885
}
}
]
}
But then when we run the report afterwards, this particular conversion is no longer part of it: It doesn't just not take the update, the conversion has been completely removed.
I've verified that the Ordinal, timestamp, gclid, activityId, and configuration IDs all match. Any idea where my conversions are going?
I will note that we are running the batchUpdate command for creations as well. I'm not sure if that would have anything to do with it, but the records do get created as normal.

Why doesn't my test run tearDownAfterTestClass when it fails

in a test i am writing the setUpBeforeTests creates a new customer in the database who is then used to perform the tests with so naturally when i finish the test i should get rid of this test customer in tearDownAfterTestClass so that i can create then anew when i rerun the test and not get any false positives
how when the tests all run fine i have no problem but if a test fails and i go to rerun it my setUpBeforeTests fails because i check for mysql errors in it like this
try
{
if(!mysqli_query($connection,$query))
{
$this->assertTrue(false);
}
}
catch (Exception $exc)
{
$msg = '[tearDownAfterTestClass] Exception Error' . PHP_EOL . PHP_EOL;
$msg .= 'Could not run query - '.mysqli_error($connection). PHP_EOL;;
$this->fail($msg);
}
the error i get is that there is a primary key violation which is expected cause i'm trying to create a new customer using the same data (primary key is on email which is also used to log in) however that means when the test failed it didn't run tearDownAfterTestClass
now i could just move everything in tearDownAfterTestClass to the start of setUpBeforeTests however to me that seems like bad programming since it defeates the purpose of even have tearDownAfterTestClass
so i am wondering, why isn't my tearDownAfterTestClass running when a test fails
NOTE: the database is a fundamental part of the system i'm testing and the database and system are on a separate development environment not the live one, the backup files for the database are almost 2 GBs and takes almost 1/2 an hour to restore, the purpose of the tear down is to remove any data we have added because of the test so that we don't have to restore the database every time we run the tests