Yii functional testing - yii

I try to do functional test like to example into The Definitive Guide to Yii.
This is my fixture into tbl_showcase.php:
return array(
'sample1'=>array(
'title'=>'Welcome',
'content'=>'A main page test',
'row_type'=>1,
),
'sample2'=>array(
'title'=>'About',
'content'=>'An about page test',
'row_type'=>2,
),
);
This is my test class:
class ShowcaseTest extends WebTestCase
{
public $fixtures = array('showcase'=>'Showcase');
public function testIndex()
{
$this->open('/');
$this->assertTextPresent($this->showcase['sample1']['title']);
$this->assertTextPresent('Welcome');
$this->assertTextPresent($this->showcase['sample1']['content']);
$this->assertTextPresent('A main page test');
}
}
I start test
phpunit functional/ShowcaseTest.php
and get next error:
Time: 8 seconds, Memory: 6.25Mb
There was 1 error:
1) ShowcaseTest::testIndex
Exception: Unknown property 'name' for class 'ShowcaseTest'.
/home/myfolder/web/yii/framework/test/CWebTestCase.php:48
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.

You can get around it by explicitly giving name property to ShowcaseTest class, like that:
public $fixtures = array('showcase'=>'Showcase');
public $name = 'Something Meaningful';
Or look into fixtures file itself, where properties are defined.

Related

Lumen 8 - Using Faker in tests makes InvalidArgumentException: Unknown format "name"

I'm using Lumen default Tests only added this line to the test :
$users = \App\Models\User::factory()->count(5)->create();
But i get this error when running the test :
InvalidArgumentException: Unknown format "name"
I did't touch the UserFactory Class i include it below , whats wrong with my code?
public function definition()
{
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
];
}
Should anybody else end up here looking for a similar issue in Laravel, make sure you include
parent::setUp();
in your setup method (if you have one). For example,
class ManageDocumentTest extends TestCase
{
public $user;
public function setUp():void
{
parent::setUp();
$this->user = User::factory()->create();
...
Uncommented these lines in app.php and its working now :
$app->withFacades();
$app->withEloquent();
You have to extend use Tests\TestCase instead of PHPUnit\Framework\TestCase.
At least, it helped me.
If you are using Tests\TestCase, calling parent::setUp(); and it still doesn't work, make sure not to call $faker before the actual test - ie. in a #dataProvider it won't work

Grails integration tests failing due to i18n message fetched during Bootstrap

I added a service method call to Boostrap.groovy in my Grails 4.0.1 application:
#GrailsCompileStatic
class BootStrap {
GrailsApplication grailsApplication
SelfAssessmentRatingService selfAssessmentRatingService
def init = { servletContext ->
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
...
SelfAssessmentRating rating = SelfAssessmentRating.first()
if (!rating) {
selfAssessmentRatingService.createRatingsFromConfig()
}
}
def destroy = {
}
}
In the service method, an i18n message is fetched for each object I have specified in setup.selfAssessmentRatings in the application config.
#GrailsCompileStatic
#Slf4j
#Transactional
class SelfAssessmentRatingService implements GrailsConfigurationAware {
MessageSource messageSource
List<Map> setupAssessmentRatings
#Override
void setConfiguration(Config co) {
List selfAssessmentRatings = co.getProperty('setup.selfAssessmentRatings', List, null)
setupAssessmentRatings = selfAssessmentRatings as List<Map>
}
/**
* Saves a SelfAssessmentRating record for each one specified in the application config.
* This method gets called if there are no SelfAssessmentRating records saved.
*/
def createRatingsFromConfig() {
if (setupAssessmentRatings == null || setupAssessmentRatings.empty) {
log.info("Skipping creating SelfAssessmentRatings because none were specified " +
"in the config: 'setup.selfAssessmentRatings'")
return
}
log.info("Saving ${setupAssessmentRatings.size()} new SelfAssessmentRating records")
for (Map map in setupAssessmentRatings) {
// SelfAssessmentRating is a domain class
SelfAssessmentRating newRating = new SelfAssessmentRating()
newRating.rating = map.rating as Integer
newRating.englishText = map.englishText
newRating.translationKey = map.translationKey
newRating.save(failOnError: true)
// Verify we have that translation. This will throw an exception if the translation is not present.
messageSource.getMessage(newRating.translationKey, [].toArray(), Locale.default)
}
}
}
Here is the default config value for setup.selfAssessmentRatings; this is in the root of application.yml so it applies to all Grails environments:
setup.selfAssessmentRatings:
- {rating: 1, translationKey: "example.selfAssessment.noExperience", englishText: "No Experience or Knowledge"}
- {rating: 2, translationKey: "example.selfAssessment.someExperience", englishText: "Some Experience or Knowledge"}
- {rating: 3, translationKey: "example.selfAssessment.functionIndependently", englishText: "Able to function independently in this area"}
And I have those three messages defined in grails-app/i18n/messages.properties:
example.selfAssessment.noExperience=No Experience or Knowledge
example.selfAssessment.someExperience=Some Experience or Knowledge
example.selfAssessment.functionIndependently=Able to function independently in this area
My integration tests all pass in CircleCI (./gradlew -Dgrails.env=circleci integrationTest), but on my local machine I get the following error for each integration test:
org.springframework.context.NoSuchMessageException: No message found under code 'example.selfAssessment.noExperience' for locale 'en_US'.
at org.springframework.context.support.AbstractMessageSource.getMessage(AbstractMessageSource.java:161)
at com.hclabs.ojt.step.SelfAssessmentRatingService.$tt__createRatingsFromConfig(SelfAssessmentRatingService.groovy:46)
Does anyone know how I can get my integration tests to pass again locally ?
Is there an argument I could add or an environment variable to set when calling ./gradlew integrationTest on my local machine so that Grails can find the messages in grails-app/i18n/messages.properties?

How to create unit test for the function "beforeControllerAction" extended from yii framework

I need some idea, to create unit test for the action 'beforeControllerAction', which is extended from yii framework.
beforeControllerAction is parent method from any 'mycontroller' app controller, coming from framework core. You don't need to test specific core framework code (is already tested). You need to test your own code.
One way to test your controller is to extend/inherit your own 'mycontroller' controller first and build a test for it. Taken from this excellent article:
Create your unit test class under the protected/tests/unit
folder and name it the same as your class name you want to test,
adding a Test word after it.
In my case, I will create a file named ApiControllerTest.php that
contains all tests for ApiController.php class.
<?php
// You can use Yii import or PHP require_once to refer your original file
Yii::import('application.controllers.ApiController');
class ApiControllerTest extends ApiController
{
}
Open your ApiControllerTest.php unit test class in step #1
above and make it something similar like this (based on your
requirement and structure):
class ApiControllerTest extends CTestCase
{
public function setUp()
{
$this->api = new ApiController(rand());
}
public function tearDown()
{
unset($this->api);
}
}
Let’s try to test one single method in my ApiController.php, that is
formatResponseHeader. This is what it is doing.
public function formatResponseHeader($code)
{
if (!array_key_exists($code, $this->response_code))
{
$code = '400';
}
return 'HTTP/1.1 ' . $code . ' ' . $this->response_code[$code];
}
Now, to test this method, I’ll open ApiControllerTest.php and add this
code below after setUp() and before tearDown() methods:
public function testFormatResponseHeader()
{
$this->assertEquals('HTTP/1.1 400 Bad Request',$this->api->formatResponseHeader('400'));
$this->assertEquals('HTTP/1.1 200 OK',$this->api->formatResponseHeader('200'));
$this->assertEquals('HTTP/1.1 400 Bad Request',$this->api->formatResponseHeader('500'));
$this->assertNotEquals('HTTP/1.1 304 Not Modified',$this->api->formatResponseHeader('204'));
}
Save the change in ApiControllerTest.php and then try to run this in
protected/tests directory:
phpunit .

behat 3 - Using constructor breaks output

I followed the tutorial on http://docs.behat.org/en/latest/quick_intro_pt1.html.
But when I have implemented the feature and running behat it is said in the tutorial that I should get an error: "Fatal error: Class 'Shelf' not found."
I did not get that error. Only the output of the user story:
$ vendor/bin/behat
Feature: Product basket
In order to buy products
As a customer
I need to be able to put interesting products into a basket
Rules:
- VAT is 20%
- Delivery for basket under £10 is £3
- Delivery for basket over £10 is £2
class FeatureContext implements SnippetAcceptingContext
{
private $shelf;
private $basket;
public function __construct()
{
$this->shelf = new Shelf();
$this->basket = new Basket($this->shelf);
}
/**
* #Given there is a :product, which costs £:price
*/
public function thereIsAWhichCostsPs($product, $price)
{
$this->shelf->setProductPrice($product, floatval($price));
}
It looks like, when I am using a constructor this happening and the output of behat is just the user story but not the tests.
Even if I put an exit() in the function the exit() is not happening.
I have tried this with different projects in PHPStorm. It is always the same.
I am wondering how I could get the expectedt error: "Fatal error: Class 'Shelf' not found."
I am using behat 3.0.14: I have used composer to install it.

PHPUnit Test failing when internal Array is set

have numerous tests working, but my actual test of some objects is failing and I am not sure why. When I step through the code in a simple test, I can see that what I am trying to test is defined, but PHPUnit fails the testing.
I have small code samples edited below to try to illustrate the issue without too much noise.
Very simple subset of a class definition.
class UTIL_CATEGORY_SCOPE extends UTIL_MESSAGE_DATA
{
function __construct($CategoryNo = NULL, $CategoryName = NULL)
{
$this->DeclareClassFields_();
$this->CategoryName = $CategoryName;
$this->CategoryNo = $CategoryNo;
}
private function DeclareClassFields_()
{
$this->Fields['CategoryNo'] = new UTIL_ICAP_FIELD('CCL', 6, 'Category', 8);
$this->Fields['SubCategoryNo'] = new UTIL_ICAP_FIELD('SCC', 6, 'Sub-Category', 12);
$this->Fields['SubSubCategoryNo'] = new UTIL_ICAP_FIELD('SSC', 6, 'Sub-Sub-Category', 12);
}
}
Normal code in Netbeans debugger to see this works.
$Category = new UTIL_CATEGORY_SCOPE();
Dump contents for comparison for the PHPUnit test samples to follow.
var_dump($Category);
class UTIL_CATEGORY_SCOPE#1 (4) {
public $TheMessage_ =>
class MESSAGE_DATA#2 (0) {
}
This is OK. Expected and works, as the class InstanceOf can be tested and passes correctly.
Internally, there is a list of fields maintained in an array, which is an array of class objects, that uses magic methods for get/set values, etc... Is the Array initialized?
var_dump($Category->Fields);
array(3) {
'CategoryNo' =>
class UTIL_ICAP_FIELD#3 (14) {
public $FieldCode =>
string(3) "CCL"
public $FieldLength =>
int(6)
public $FieldTitle =>
string(8) "Category"
}
'SubCategoryNo' =>
class UTIL_ICAP_FIELD#4 (14) {
public $FieldCode =>
string(3) "SCC"
public $FieldLength =>
int(6)
public $FieldTitle =>
string(12) "Sub-Category"
}
'SubSubCategoryNo' =>
class UTIL_ICAP_FIELD#5 (14) {
public $FieldCode =>
string(3) "SSC"
public $FieldLength =>
int(6)
public $FieldTitle =>
string(16) "Sub-Sub-Category"
}
}
Array is initialized as expected.
Check that the Array exists and the individual items may be accessed.
if (array_key_exists('CategoryNo', $Category->Fields))
echo 'Array Key Exists';
Array Key Exists
if( $Category->Fields['CategoryNo'] instanceof UTIL_ICAP_FIELD )
echo 'Yes';
Yes
All is reporting as expected.
PHPUnit Test partial:
class TEST_UTIL_CATEGORY_SCOPE extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
}
public function testObjectCreation()
{
$CategoryInfo = new UTIL_CATEGORY_SCOPE();
$this->assertInstanceOf('UTIL_CATEGORY_SCOPE', $CategoryInfo);
$this->assertInstanceOf('UTIL_DATA_STRUCTURE', $CategoryInfo);
}
public function testConstructFieldOrder()
{
$CategoryInfo = new UTIL_CATEGORY_SCOPE(1500, 'Category Name');
$this->assertEquals(1500, $CategoryInfo->CategoryNo);
$this->assertEquals('Category Name', $CategoryInfo->CategoryName);
}
/**
*
*/
public function testConstructDefaults()
{
$CategoryInfo = new UTIL_CATEGORY_SCOPE();
$this->assertNull($CategoryInfo->CategoryNo);
$this->assertNull($CategoryInfo->CategoryName);
}
These tests pass as expected. However, given the dumps of information above, the following 2 tests fail, even though the test run and var_dump show that the values are initialized and present as expected.
public function testFieldsCreated()
{
$CategoryInfo = new UTIL_CATEGORY_SCOPE();
$this->assertArrayHasKey('CategoryNo', $CategoryInfo->Fields);
$this->assertArrayHasKey('SubCategoryNo', $CategoryInfo->Fields);
$this->assertArrayHasKey('SubSubCategoryNo', $CategoryInfo->Fields);
}
Errors Created:
1) TEST_UTIL_CATEGORY_SCOPE::testFieldsCreated
Failed asserting that an array has the key 'CategoryNo'.
Next Test
public function testICAPFieldTypes()
{
$CategoryInfo = new UTIL_CATEGORY_SCOPE();
$this->assertInstanceOf('UTIL_ICAP_FIELD', $CategoryInfo->Fields['CategoryNo']);
$this->assertInstanceOf('UTIL_ICAP_FIELD', $CategoryInfo->Fields['SubCategoryNo']);
$this->assertInstanceOf('UTIL_ICAP_FIELD', $CategoryInfo->Fields['SubSubCategoryNo']);
}
Errors Created:
2) TEST_UTIL_CATEGORY_SCOPE::testICAPFieldTypes
Failed asserting that null is an instance of class "UTIL_ICAP_FIELD".
I am not sure how to continue as this causes errors when I can see that the objects are created, the arrays populated as I would expect. I have to mark these tests as Incomplete for now, to allow our test suite to continue.
Does anyone have any ideas?
I found the solution, after some deep inspection of the class. The array I was attempting to access was defined as PROTECTED, so the PHPUnit Test Framework could not access the value.
There is two solutions to get around this.
Declare the array as PUBLIC to make it accessible.
Use Reflection in the Tests to make it accessible for the tests only.
Option 2 is our preferred solution, but for the immediate needs of the project, and the time for the other changes, Option 1 (PUBLIC) was used temporarily.
Thanks to those who helped to try to solve my issue.