Add tests for Config Store API function: loadConfigFromFilesystem#21
Conversation
The store is generic and doesn't have anything to do with WordPress. You can use it on any PHP project. Keeping it decoupled from WordPress is a good strategy. What do you do instead? Look at the WordPress-specific code to find the root cause. Why is something trying to get a configuration that doesn't exist? Fix the problem there and no in the store itself. |
|
@hellofromtonya WordPress fires a hook The simplest and earliest way that I can intervene to prevent the invocation of the function register_meta_boxes() { // rest of the function… While that allows the
Since If that's not a useful approach, can you suggest another way to approach the problem? |
|
@rgadon107 There are a couple of strategies to consider:
Which strategy should you select? Start by asking yourself a question:
Think about it. |
|
@hellofromtonya Working at the front end of the call stack (where the function I don’t think it’s necessary to add an API function
Then in What do you think of this approach? The next step would be to write a passing unit test for |
|
@rgadon107 No code except the API should be calling Instead, consider returning something, but not throwing an error. Let's walk through a thought experiment:
What do you think? |
|
@hellofromtonya This makes sense. Since we already have a 'guardrail' condition inside We don't touch |
|
@rgadon107 Almost there. Good job. I'd go further though.
|
|
@hellofromtonya Yes, I agree. The first guardrail condition in
Values regarded as empty include:
There will be no Exception thrown in I will go back through the commits on this branch and review the changes I submitted for your review. I'll probably just revert the branch to an earlier commit and drop those changes. Then we can move forward with the other edge cases for |
- Function should merge defaults with config and return store key.
f643d90 to
f50fa03
Compare
1) Function should store a config and return a store key. 2) Function should return an error when the argument $path_to_file is empty. - fixed test description and method name.
f50fa03 to
b548e39
Compare
- Test function should overwrite stored configuration and return store key from file configuration.
|
@hellofromtonya Hi Tonya, I wrote 4 tests today for edge cases #1 - 4 for
I'm using BM's My test returns the following error message:
Can you help me to think through what I'm doing wrong? ================================================= Update: I was using BM's I need to go back and listen again to the episodes on the use of This branch is ready for CR and merge with |
Why? It's an integration test.
|
@rgadon107 I just pushed commits to fix the unit tests and add integration tests for this API function. A few notes for you:
Look the tests over. Ask questions. When you're ready, flag me and I'll merge this one. |
loadConfigFromFilesystem
| ->andReturn( [ 'foo', $config ] ); | ||
| Monkey\Functions\expect( '\KnowTheCode\ConfigStore\_merge_with_defaults' )->never(); | ||
| Monkey\Functions\expect( '\KnowTheCode\ConfigStore\_the_store' ) | ||
| ->twice() |
There was a problem hiding this comment.
@rgadon107 Notice that we are invoking this 2x.
| ->twice() | ||
| ->with( $path_to_file ) | ||
| ->andReturn( [ 'foo', $config ] ); | ||
| Monkey\Functions\expect( '\KnowTheCode\ConfigStore\_merge_with_defaults' )->never(); |
There was a problem hiding this comment.
@rgadon107 Notice that we are checking that this function does not get invoked.
| ->with( 'foo', $merged_config ) | ||
| ->andReturn( true ); | ||
|
|
||
| $this->assertSame( 'foo', loadConfigFromFilesystem( $path_to_file, $defaults ) ); |
There was a problem hiding this comment.
@rgadon107 Look at each of the mocked internal function dependencies. We are checking:
- The number of times each is invoked, i.e.
once(). - The arguments we expect each to received, i.e.
with. - The value that is returned, i.e.
andReturn.
When we invoke loadConfigFromFilesystem(), each of these internal functions will be exercised. BrainMonkey is checking the number of times and arguments for us. It then mocks the function out and returns the value we coded.
| Monkey\Functions\expect( '\KnowTheCode\ConfigStore\_merge_with_defaults' )->never(); | ||
| Monkey\Functions\expect( '\KnowTheCode\ConfigStore\_the_store' )->never(); | ||
|
|
||
| loadConfigFromFilesystem( $path_to_file ); |
There was a problem hiding this comment.
@rgadon107 Notice how this integration test is constructed. What is it doing?
- It's validating that
_load_config_from_filesystem()does do what we expect:- Loads the config from file.
- throws the error we expect
_merge_with_defaultsdoes get called._the_storedoes get called.
Writing a test in this way makes it very clear as to what behavior we expect and don't expect to happen.
|
@hellofromtonya Well, this CR was surprising and instructive. It's was a useful exercise in the application of BM and distinguished the construction of unit versus integration tests. This branch will be useful going forward to better understand how to think about and construct unit & integration tests. |

@hellofromtonya Hi Tonya! During spare moments this past week, I sat down and worked a bit on the project. I reviewed your comments for PR #20 and merged the
developmentbranch into my local version ofadd/loadConfigFromFS).My latest set of commits address edge case #6;
Well, I changed the first conditional in
_the_store()to return an Exception rather than an empty array stored in$config_store.Something interesting happened when I attempted to log in and visit the site Admin page.
_the_store()threw an Exception! According to the stack track presented by Whoops!, when the site starts up and calls the API functiongetAllKeysStartingWith( $starts_with ), there's no meta_key configuration stored in_the_store. So instead of returning an empty array, we're now throwing an Exception.The Exception can be avoided by adding an
! is_adminconditional tag to the first conditional in_the_store(). While that will display the site Admin, the unit tests for_theStoreno longer pass. ;-(Your thoughts?