Magento 2.3.x – Unit Tests with ScopeConfigInterface

Magento2 Teaser

Imagine you have a helper class that is responsible for downloading and processing JSON files. This is something you don’t want to test manually all the time. I didn’t implement many unit tests in the past, simply because it wasn’t necessary or just not scoped in a project. However, there are cases where you actually save a lot of valuable time with just a few simple unit tests.

In this article I would like to show you how to inject store configurations ( ScopeConfigInterface ) to your mocked classes which are necessary to test multiple scenarios. In the following example I am going to test a helper class and make sure the following scenarios are working as expected.

  1. Is the module enabled in Stores > Configuration > General?
  2. Is a URL defined?
  3. Does the URL return a correct HTTP response?
  4. Is the downloaded content a valid JSON string?

Here is how my module looks like. I basically created a new helper Helper\Curl.php and a unit test file Test\Unit\Helper\CurlTest.php.

I’ve added some basic methods to the helper, such as isEnabled(), getFileUrl(), getStatusCode(), isJson() and downloadFile(). Nothing fancy, just a helper that can download a file.

Usually if you want to use system variables from core_config_data you have to inject the ScopeConfigInterface in your constructor. In unit tests it is quite similar. First, you have to create a mockup of the ScopeConfigInterface.

Next, you need a mockup of the Context, but this is not always the case.

Now you can inject these two mockups to the helper by using setConstructorArgs like in the below example.

Now you can define values for the scope configuration. This allows you to enable or disable your module or set random values and see how your code behaves. In the below example, I simply enable the module ( $isEnabled ) and set the file url ( $fileUrl ) to https://raw.githubusercontent.com/ljharb/json-file-plus/master/package.json which I will test with assertEquals and assertNotContains.

I also define an expected value for the CURL httpStatus and an expected return value of isJson(). Okay, lets run the test and see what happens.

All assertions within the test have succeeded. Let’s see what happens when I change the URL slightly. It should return a 404.

Yes, the test fails because I’ve received a status code 404 instead of 200.

That’s it. If you have questions or need help, please let me know in the comments.