I have a class:
class Hello {
function doSomething(&$reference, $normalParameter) {
// do stuff...
}
}
Then I have a controller:
class myController {
function goNowAction() {
$hello = new Hello();
$var = new stdClass();
$var2 = new stdClass();
$bla = $hello->doSomething($var, $var2);
}
}
The "goNow" action I call using my tests like so:
$this->dispatch('/my/go-now');
I want to mock the "doSomething" method so it returns the word "GONOW!" as the result. How do I do that?
I've tried creating a mock
$mock = $this->getMock('Hello ', array('doSomething'));
And then adding the return:
$stub->expects($this->any())
->method('discoverRoute2')
->will($this->returnValue("GONOW!"));
But I'm stumped as to how to hook this up to the actual controller that I'm testing. What do I have to do to get it to actually call the mocked method?
You could create a mock for the reference, or if it is just a simple reference as your code shows, send a variable. Then the normal mock call may be called and tested.
$ReferenceVariable= 'empty';
$mock = $this->getMock('Hello ', array('doSomething'));
$stub->expects($this->any())
->method('discoverRoute2')
->will($this->returnValue("GONOW!"));
$this->assertEquals('GONOW!', $stub->doSomething($ReferenceVariable, 'TextParameter'));
Your example code does not explain your problem properly.
Your method allows two parameters, the first being passed as a reference. But you create two objects for the two parameters. Objects are ALWAYS passed as a reference, no matter what the declaration of the function says.
I would suggest not to declare a parameter to be passed as a reference unless there is a valid reason to do so. If you expect a parameter to be a certain object, add a typehint. If it must not be an object, try to avoid passing it as a reference variable (this will lead to confusing anyways, especially if you explicitly pass an object as a reference because everybody will try to figure out why you did it).
But your real question is this:
But I'm stumped as to how to hook this up to the actual controller that I'm testing. What do I have to do to get it to actually call the mocked method?
And the answer is: Don't create the object directly in the controller with new Hello. You have to pass the object that should get used into that controller. And this object is either the real thing, or the mock object in the test.
The way to achieve this is called "dependency injection" or "inversion of control". Explanaitions of what this means should be found with any search engine.
In short: Pass the object to be used into another object instead of creating it inside. You could use the constructor to accept the object as a parameter, or the method could allow for one additional parameter itself. You could also write a setter function that (optionally) gets called and replaces the usual default object with the new instance.
Related
I would like you to share your experience on the matter of using some common object by different components of a library (or an application). I'd like to understand, which practice is better, which way is more "ecological".
Let's imagine that we have some complex library that consists of a bunch of classes: Library, Library::Foo, Library::Foo::Bar and many other ones. An application that uses the library initializes a Library-classed object, at some stage this object initializes some quantity of Library::Foo-classed objects, they initialize Library::Foo::Bar-classed objects and so on.
And now let's imagine that there is the Library::Logger class that is being used by all components. It's being initialized only once by the constructor of the Library class and all other sub-classes need it for their logging purposed.
The question is: how to let them all have the reference to this object?
I see the following ways to acheive it:
Passing it to the constructor
When a Library-based object initializes a Library::Foo-classed object, it passes the reference to the logger to the newly-created object as a parameter:
$self->_set_logger(Library::Logger->new());
my $logger = $self->_get_logger;
my $foo = Library::Foo->new(logger => $logger);
So the Library::Foo-classed object could get the logger and even pass it to a Library::Foo::Bar-classed object when it's needed:
my $logger = $self->_get_logger;
my $bar = Library::Foo::Bar(logger => $logger);
Accessing it as a method
When a Library-based object initializes the Library::Foo-based object, it passes the reference to itself to the newly-created object:
$self->_set_logger(Library::Logger->new());
my $foo = Library::Foo->new(papa => $self);
So the Library::Foo-based object could access the logger this way:
$my logger = $self->_get_papa->_get_logger;
my $bar = Library::Foo::Bar(papa => $self);
It breaks encapsulation, but it also lets the Library::Foo-based object to get other data from its "papa".
Using a global variable
Also we can store the reference to the logger in some global variable, so any other object could access it this way:
$logger = $Library::_LOGGER;
Well, it really sucks, I know... :)
...
So, what do you think, which way seems to be better? What alternative way would you propose? How do you solve this problem for yourself? Would you pass the data to the "child" manually or would you let it to get the data from the "parent"?
Many thanks in advance!
There is no answer to your problem. It realy depends on your exact use-case. If (just guessing) you only want to have exactly one Logger in your Library, I think using the software pattern of a "singleton" might exactly fit. E.g.
package Library::Logger;
use strict;
my $logger;
sub new {
unless ($logger) {
.... initializing $logger ...
}
return $logger;
}
and in each of your sublclasses you can access it by
Library::Logger->new()->...
HTH
Georg
Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.
I have a WinJS class defined as follows and would like to use a member function in the constructor:
WinJS.Class.define(
function() {
setInterval(myMemberFunction, 100);
},
{ // Member variables
myMemberFunction: function() {
// Do something
}
});
Unfortunately it looks like I can't resolve member functions in that manner in the constructor. This code all lives in a module so I could move myMemberFunction up the hierarchy and access it from the constructor, however the drawback is that "this" would no longer refer to the instance of my WinJS class. What's the recommended method for accessing instance members in a WinJS from the constructor?
Generally speaking, you refer to any method or property using "this," as in this.myProperty. In the case of event handlers, you need to make sure that the "this" that you see inside the handler is the instance "this". That's the purpose of the bind method of a function object. So you do this:
setInterval(this.myMemberFunction.bind(this), 100);
This makes sure that you bind the right "this" instance to the callback. Because I've seen this question pop up frequently (use of .bind is all over the Windows SDK samples), I wrote about this in more detail on http://www.kraigbrockschmidt.com/2012/11/28/purpose-function-dot-bind/.
Just to note, this is pure JavaScript; nothing particular to WinJS or Windows Store apps.
I've seen this question regarding partial stubs, but it does not quite tell me what I need to know.
I understand that, if I am using a Moles stub for a class (let's say, for DataService, I'm using SDataService), I can set the CallBase property to true so that, if there is no delegate for a particular method, the base implementation's method will be called. Great, but how do I assign a delegate to a particular method in this case?
If there is no way to do that, say I have an interface IDataService that I stub using SIDataService. I can easily assign a delegate to a method here. But, how do I tell it to call the corresponding method on DataService (an implementation of IDataService) if there is no delegate for a given method?
Thank you!
Edit:
I see now that the method needs to be virtual to be overridden in the first scenario above. I don't think that makes a whole lot of sense, but it is what it is.
So, focusing on the second scenario, would I have to create a Behavior? (And why isn't there one already for stubs like there is for moles?) Or is there a simpler way?
Delegates (detours) are set to stubs types the same way as mole types. For example, SIDataService.GetMemberProfile() is configured to return a mock object like this:
var memberMock = new Member() { Firstname="Joe", LastName="Schmoe" };
var stub = new SIDataService();
stub.GetMemberProfileMember = i => memberMock;
I couldn't find any reference on how to use a parent form element in a subclassed form. May be because it's obvious to everyone but me. It's got me stumped. This is what I tried.
At first, within my form constructor I called
parent::__construct($options = null);
then accessed the parent elements like this
$type = parent::setName($this->type);
The problem was that ALL the parent form elements would display whether explicitly called or not. Someone said, "don't use __construct(), use the init() function instead. So I changed the constructor to init(), commented out the parent constructor, then ran the form. It bombed saying it couldn't pass an empty value for setName(). I commented out all the seName() calls and the form ran, but only displayed the elements instantiated in the subclassed form.
My question is this: If I don't use the parent constructor, how do i get and use the parent's form elements?
Solved: Since the constructor was switched to init, the call to the parent also needed to be switched. Easy for someone with php background. Not so much for one who doesn't.
Use
parent::init();
Solved: Since the constructor was switched to init, the call to the parent also needed to be switched. Easy for someone with php background. Not so much for one who doesn't.
Use
parent::init();
You should learn OOP principles first. Obviously you have no understanding of it whatsoever. You need to call parent::init() in you Form_Class::init() method as you wrote, but why? Because otherwise the parent method is not called and is overriden by the From_Class method.
Other thing is that when you have a parent class "SuperForm" with input and submit, then your "SuperForm_Subclass" would have the same elements assigned. There is no need to use "parent::*" to access element (only exception would be if you used static SuperForm variable to store them - which makes no sense).
You can easily use $this->inputElement and $this->submitElement inside your SuperForm_Subclass like you would in the SuperForm class.
In your example you could used the __contruct() as good, but with the same condition of calling the parent constructor. You would be able to access elements generated there too...