Code and write up - https://codereviewvideos.com/course/let-s-build-a-wallpaper-website-in-symfony-3/video/using-phpspec-to-test-our-filemover
We have all the pieces in place to start writing code that we can test using PhpSpec. Now we're going to create our tested FileMover service.
Show More Show Less View Video Transcript
0:00
Hi, I'm Chris from CodeReviewVideos.com and in this video we're continuing our FileMover
0:08
test and implementation. Now going back to our implementation, to actually be able to move a file, we can do this in
0:15
a multitude of ways. The three that I can think of off the top of my head are to use either PHP's built-in
0:20
functions, or we can use something like FlySystem or Galfret, some sort of file system abstraction
0:26
or we can use the Symfony file system component. Well, as we're using Symfony anyway, we might as well make use of the components it provides
0:33
We've already got them. We don't need to include any other dependencies. And as this is a Symfony service, the way in which we'll get access to that file system is to simply inject it
0:42
Now, if you're unsure, what we can do at this point is do a PHP bin console, debug, container
0:48
and then we'll pass in file system as the thing that we're looking for. And you can see here it dumps out all the service information for us
0:54
The one that we're interested in here will be the service ID, which is file system
0:58
all one word lowercase and because we're going to be injecting this we'll need to prefix it with
1:03
the at symbol to indicate that it's a service but knowing this if we're going to inject it we can go
1:08
ahead set this up via the constructor to inject our concrete implementation of the symphony file
1:14
system and notice the use statement's been brought in i'm going to alt and return on that on the mac
1:19
to initialize the fields that should all be good and then i going to add the implementation here so it this file system and then there a bunch of methods that you can do with it the one we interested in is rename we going to rename from the existing file path to the new file path and unfortunately this is actually a
1:35
void method if we look at it it doesn't return anything it throws a couple of things and that's
1:40
quite useful but doesn't actually return anything which is why we can't just simply return the
1:44
outcome of this that's why we have to return true so now if we try and run our tests again
1:49
you can see that both of them have broken this is to be expected because now we've just changed
1:54
the implementation to expect that we're passing in a file system instance but inside our spec
1:59
we're not really doing that at all so we can start fixing this by injecting a file system
2:05
into each test making sure that we've got the right use statement and i'll just call that fs
2:09
just to make it a little bit more shorthand and again we can do it for this one and then what we
2:14
can do, apologies, what we can do is do this, be constructed with, and I can say fs to make sure
2:20
that whenever we call our file mover, it gets constructed with an instance of the file system
2:26
So again, we'll run our test now and we're back to passing because we're injecting the expected dependency. But of course, you don't want to keep having to do this for every single
2:33
test that you create. So PHP Specs got a better solution to this, which is the let function. So
2:39
we'll just say let, create that, and we'll say be constructed with. That's cool. And that's cool
2:44
We don need these anymore so just get rid of them But I do need it inside the let method or the let function So now we should still have two passing tests which we do albeit with a little less duplication
2:57
OK, but let's look back at what our tests are actually testing. So we've got it is initializable and that checks that this file mover class exists
3:04
And also now in our case that our constructor depends on a file system
3:09
It's not really testing anything in terms of our implementation. For that, we've added our own test
3:13
It can move a file from temporary to controlled storage. And we call move. with our current location our new location it should return true and that test is passing
3:20
we're not actually testing anything to do with this injected file system so this isn't actually
3:26
an instance of the file system it's called a collaborator and we can see this if we cheat a
3:31
little bit and we'll do a dump here and just rerun our test now and you can see that what's
3:36
been dumped out is an object that's an instance of a php spec collaborator and effectively what
3:42
this allows us to do is completely fake out the dependencies but also spy on them by which i mean
3:47
that we can check now that inside our file mover this file system renamed was called with these two
3:54
expected arguments so let's do that so we've got let file system what we're going to need to do is
3:59
get access to this file system a little later on in our test and to do that all we need to do is
4:04
say this file system or whatever property you wish to create equals fs and then we'll just add that
4:11
as a private field. OK so we constructed with it and everything And then we go into our test And after our test is run what we could now do is say this file system rename with these two properties or two arguments should
4:24
I say should have been called so we expect this file system rename with that and that to have been
4:30
called and if so then we should have a passing test that's quite cool and what it means is if we
4:36
jump inside our file mover maybe we change this out to be just one two three just to break it
4:41
run our tests you can see that we didn't quite meet the requirements of our tests so we know
4:46
even though we're not testing the symphony component which has its own unit tests and is
4:51
completely isolated from us we know that if we send in the right arguments assuming that code
4:56
all works that symphony are providing and that's a fair assumption to make then our code should
5:00
behave in line with that so that's really useful in my opinion and again just to bring that out
5:05
rerun the tests and we're all good so really the only thing that's left to do at this point is to
5:10
make sure that we have the appropriate service definition set up. So this is really straightforward
5:15
We have app service file mover. It's going to have the class of app bundle service file mover
5:22
And we know now that it takes one argument which is the at file system. So let's just take a quick
5:28
copy of that. Do a php bin console debug container. Paste that in and you can see well it didn't
5:34
throw an error so we can be pretty certain this service is properly configured
5:40
Thank you
#Web Services
#Computer Science
#Machine Learning & Artificial Intelligence
