Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Config\Services for testing #40

Closed
wants to merge 1 commit into from

Conversation

kenjis
Copy link
Member

@kenjis kenjis commented Mar 30, 2016

CodeIgniter system code uses Config\Services class as service locator:

$this->router = Services::router($routes, true);

In some cases when testing, we want to change the return value (object). For example, we want to use a mock object. Or sometimes we want to reset shared objects.
But there is no way to do so.

This PR provides a special Config\Services for testing, which has a method to inject an instance, and a method to reset shared objects.

@vonalbert
Copy link
Contributor

And what if we provide at core level a basic Services class, let say CodeIgniter\Services, that can be extended by Config\Services? This class (as I see it) should be the copy of the actual Config\Services, because it should define any service used by the framework.
Using this approach there's no need to redefine an almost identical class for testing and, as a plus, the app developer does not have every single service for the framework in his Config\Services but can override only what he need.

@kenjis kenjis closed this Mar 30, 2016
@lonnieezell
Copy link
Member

@vonalbert I had considered that, but in the end decided it was better for the developer to be able to see at a glance exactly what all of the classes were. It leaves them more in control, and keeps them out of the system directory. Has the added benefit of one less file lookup, too, but that wasn't the reason.

@kenjis
Copy link
Member Author

kenjis commented Mar 30, 2016

@vonalbert Thank you for your comment.

I added the code like the following to every method for services. So if we have a base class, we still have to redefine almost all methods.

@@ -121,6 +162,11 @@
         */
        public static function exceptions(App $config = null, $getShared = false)
        {
+               if (isset(static::$mocks[__FUNCTION__]))
+               {
+                       return static::$mocks[__FUNCTION__];
+               }
+
                if (empty($config))
                {
                        $config = new App();

@vonalbert
Copy link
Contributor

@kenjis Uhm that's true! My fault

@lonnieezell You're right, maybe it's better leave Services alone 👍

@kenjis kenjis deleted the add-services-for-testing branch March 30, 2016 20:20
@kenjis
Copy link
Member Author

kenjis commented Mar 30, 2016

@vonalbert But I also don't want to redefine an almost identical class for testing. So if there is a better way, I hope to reuse the code. Unfortunately I can't find better way.

@kenjis
Copy link
Member Author

kenjis commented Mar 31, 2016

@vonalbert See #47

nowackipawel added a commit to nowackipawel/ci4-old that referenced this pull request Dec 22, 2018
I wrote it and works like a charm. Slightly more efficient, because I  some of  array_key_exists don't exist anymore ;). 
But... I noticed an issue when I am trying to save this entity. Property which is set to null is excluded from INSERT what should cause problem if default column value is not set to null but different value - in that case we cannot save null during insert.

In my case should be:
```
INSERT INTO `t_table_search` (`dcs_identifier`, `dcs_conditions`, `dcs_dsc_id`) VALUES ('e77d630b7be1484cb4b7b4f8dbc15c45', '{\"v-school\":[\"1\"],\"v-center\":[\"44\"]}', NULL) // dcs_dsc_id = null;
```
it is:
```
INSERT INTO `t_table_search` (`dcs_identifier`, `dcs_conditions`) VALUES ('e77d630b7be1484cb4b7b4f8dbc15c45', '{\"v-school\":[\"1\"],\"v-center\":[\"44\"]}')// no null for dcs_dsc_id
```

 I think it is because of entity value of property in _original is the same as actual value of property (i.e.: dcs_dsc_id == null)


```object(App\Entities\entityname)codeigniter4#40 (7) {
  ["dcs_identifier":protected]=>
  string(32) "e77d630b7be1484cb4b7b4f8dbc15c45"
  ["dcs_conditions":protected]=>
  string(52) "{"driving-school":["1"],"examination-center":["44"]}"
  ["dcs_dsc_id":protected]=>
  NULL
  ["dcs_updated_at":protected]=>
  NULL
  ["_options":protected]=>
  array(3) {
    ["casts"]=>
    array(3) {
      ["dcs_identifier"]=>
      string(6) "string"
      ["dcs_conditions"]=>
      string(10) "json-array"
      ["dcs_dsc_id"]=>
      string(11) "?json-array"
    }
    ["dates"]=>
    array(2) {
      [0]=>
      NULL
      [1]=>
      string(14) "dcs_updated_at"
    }
    ["datamap"]=>
    array(0) {
    }
  }
  ["_original":protected]=>
  array(4) {
    ["dcs_identifier"]=>
    NULL
    ["dcs_conditions"]=>
    NULL
    ["dcs_dsc_id"]=>
    NULL
    ["dcs_updated_at"]=>
    NULL
  }
  ["_cast":"CodeIgniter\Entity":private]=>
  bool(true)```


I saw PR month or two ago which was changing entity saving but IMHO it should be turned ON for update or replace but should NOT work for INSERT.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants