how can i store the value returned by my init to be used in my functions - coldfusion

I have the init code and it returns me a structure
public any function init() {
httpService = new http();
httpService.setUrl("#Application.baseURL#security/oauth2/token");
httpService.setMethod("POST");
httpService.addParam(type="header", name="Content-Type", value="application/x-www-form-urlencoded");
httpService.addParam(type="body", value="client_id=#application.clientID#&client_secret=#application.clientsecretID#&grant_type=#application.grant_type#");
result = httpService.send().getPrefix();
return this;
}
problem how can i use the token returned by the method in other methods, if i dump the init, i am just getting the functions, how can i use the data returned by the http
just not getting in my head, because the token is alive for 3600
Thanks

As James says, you should store the result of the http call as an instance variable. Here's one way of doing it using a property and specifying accessors=true for the component so that you can call setHttpResult() and getHttpResult() without having to write those methods. using the variables scope which will make it available to other methods within the component, but not outside.
/* Test.cfc */
component name="test"{
property name="httpResult" type="struct";
public any function init(){
//use "var" to ensure the variable is local to the function only
var httpService = new http();
httpService.setUrl("#Application.baseURL#security/oauth2/token");
httpService.setMethod("POST");
httpService.addParam(type="header", name="Content-Type", value="application/x-www-form-urlencoded");
httpService.addParam(type="body", value="client_id=#application.clientID#&client_secret=#application.clientsecretID#&grant_type=#application.grant_type#");
//store the result privately in the instance
variables.httpResult = httpService.send().getPrefix();
return this;
}
public void function someOtherMethod(){
// this method can access the result struct
var returnedContent = variables.httpResult.fileContent;
}
}
You can then use getHttpResult() inside or outside your component. For example from an external script:
test = New test(); // calls the init() method
WriteDump( test.getHttpResult() ); //auto-generated "getter"

Related

Mockery mock method inside closure

I have problem unit testing method inside closure called by call_user_func() example :
public function trans($lang, $callback)
{
$this->sitepress->switch_lang($lang);
call_user_func($callback);
}
on controller :
public function sendMail()
{
$foo = $baz = 'something';
$mail = $this->mailer;
$this->helper->trans_c('en', function() use($foo, $baz, $mail) {
$mail->send('Subject', $foo, $baz);
});
}
test case :
public function testSomething()
{
$helperMock = Mockery::mock('Acme\Helper');
$helperMock->shouldReceive('trans_c')->once(); // passed
$mailMock = Mockery::mock('Acme\Mail');
$mailMock->shouldReceive('send')->once(); // got should be called 1 times instead 0
$act = new SendMailController($helperMock, $mailMock);
$act->sendMail();
}
how can I ensure that ->send() method is called inside closure trans_c()
I tried with
$helperMock->shouldReceive('trans_c')->with('en', function() use($mailMock) {
$mailMock->shouldReceive('send');
});
no luck. :(
well it works fine with passing Mockery::type('Closure') in the second param of trans_c, but I really need to ensure that method send from mailer class is called.
A mocked class does not execute the real code by default. If you mock the helper it will check that the calls are being made but won't execute the anonymous function.
With mockery, you can configure the expectation so that the real method will be executed: passthru();
Try this:
$helperMock = Mockery::mock('Acme\Helper');
$helperMock
->shouldReceive('trans_c')
->once()
->passthru()
;
This is explained in the docs.
EDIT
Maybe you don't really need to mock the helper. If you mock the Mail class and expect the send method to be called once, just let the real helper do it.

Spy on a local function Angular Service

I have an Angular Service using a local function and doing the following work:
function myService($http,$q){
var myService = {};
var _localService = function (Table) {
return Table.something;
}
var _getSomething = function () {
return _localService('someTable');
}
var _getSomethingElse = function () {
return _localService('someTable2');
}
myService.getSomething = _getSomething ;
myService.getSomethingElse = _getSomethingElse ;
return myService ; }
Now i want to test my service with jasmine and i want to test if localService have been called.
Something like this:
spyOn(myService,"_localService");
myService.getSomething();
expect(myService._localService).toHaveBeenCalled();
How can i do that, please help.
You have to expose _localService in your service or else the spy can't find it.
Because in fact you made it private by returning myService without a _localService function.
So you can keep it private, or make it public, if it's public, it will work as is.
If you want to keep it private, then,
you shouldn't test private function, instead test what you expect as a result to the call of the public function. It will allow to refactor inner implementation and still have test to check that your code works.

PHPUnit Mock overrides existing methods

I'm writing a unit test for a REST Service connector which is using a third party tool called Httpful.
Because I do not want to send real requests to the server, I mocked the "send" method from Httpful\Request:
$mockedRequest = $this->getMock('Httpful\Request', array('send'), array(), '', false);
$mockedRequest->expects($this->once())->method('send');
This works fine, but the Request Class has a method called expects itself, which I use in my actual code to define the acceptable mime type of the response.
$this
->getRequest('GET')
->uri(ENDPOINT . $configurationId) //by default this returns a Request Object (now mocked request)
->expects('application/json') //crashes ...
->send();
When the code gets executed, I get the following error (which is understandable):
Argument 1 passed to Mock_Request_938fb981::expects() must implement interface PHPUnit_Framework_MockObject_Matcher_Invocation, string given
Is there something like a configurable prefix for methods coming from the Mock Class like "expects"?
I don't think that you will be able to do that using the PHPUnit_MockObject class. But you can code your own and use that instead.
class MockRequest extends \Httpful\Request {
public $isSendCalled = false;
public $isUriCalled = false;
public $isExpectsCalled = false;
public function uri($url) {
if($url !== '<expected uri>') {
throw new PHPUnit_Framework_AssertionFailedError($url . " is not correct");
}
$this->isUriCalled = true;
return $this;
}
public function expects($type) {
if($type !== 'application/json') {
throw new PHPUnit_Framework_AssertionFailedError($type . " is not correct");
}
$this->isExpectsCalled = true;
return $this;
}
public function send() {
$this->isSendCalled = true;
}
}
Your line for creating the mock then just becomes:
$mockedRequest = new MockRequest();
If the constructor fo
Then in your test you can verify that the methods are called with
$this->assertTrue($mockedRequest->isSendCalled);
$this->assertTrue($mockedRequest->isUriCalled);
$this->assertTrue($mockedRequest->isExpectsCalled);
This isn't a very dynamic mock but it will pass the type hinting and does your check for you. I would create this mock in the same file as your test (though be careful about not accidentally redefining this class elsewhere in your test suite). But it gets you around the problem of having expects being overridden.
The PHPUnit_Framework_MockObject_MockObject is an interface that sets the signature for expects() also which your class wouldn't meet and so there would be an error if you were able to rename the method.
https://github.com/sebastianbergmann/phpunit-mock-objects/blob/master/src/Framework/MockObject/MockObject.php

How do I scope a variable so that its available to other functions in the same CFC (a CFWheels plugin)?

I want to add a variable that can be accessed by all functions in a plugin, but I'm getting a variable undefined error. Here's my plugin:
component
mixin="Controller"
{
public any function init() {
this.version = "1.0";
return this;
}
public void function rememberMe(string secretKey="rm_#application.applicationName#") {
this.secretKey = arguments.secretKey;
}
public void function setCookie(required string identifier) {
// Create a cookie with the identifier and encrypt it using this.secretKey
// this.secretKey is not available, though, and an error is thrown
writeDump(this.secretKey); abort;
}
}
I call the plugin from my Sessions.cfc controller:
component
extends="Controller"
{
public void function init() {
// Call the plugin and provide a secret key
rememberMe("mySecretKey");
}
public void function remember() {
// Call the plugin function that creates a cookie / I snipped some code
setCookie(user.id);
}
}
When I dump this.secretKey inside the plugin, I get a variable undefined error. The error tells me that this.secretKey is not available in Sessions.cfc controller. But I'm not dumping from Sessions.cfc, I'm dumping from the plugin's CFC, as you can see. Why?
How can I scope this.secretKey in my plugin so that it can be accessed by setCookie()? So far variables and this have failed, whether I add the definitions in a function, a pseudo-constructor, or the init(). For good measure, I threw in variables.wheels.class.rememberME, to no avail.
Here's the error:
Component [controllers.Sessions] has no acessible Member with name [secretKey]
What you're doing in init() isn't going to work when in production mode. A controller's init() is only run on the first request for that controller because it get cached after that.
So this.secretKey will be set on the very first run of that controller but never for subsequent runs.
You have a few options to make this work...
I. Use the pseudo-constructor, which does run on every controller request:
component
extends="Controller"
{
// This is run on every controller request
rememberMe("mySecretKey");
// No longer in `init()`
public void function init() {}
public void function remember() {
// Call the plugin function that creates a cookie / I snipped some code
setCookie(user.id);
}
}
II. Use a before filter to call on every request:
component
extends="Controller"
{
// No longer in `init()`
public void function init() {
filters(through="$rememberMe");
}
public void function remember() {
// Call the plugin function that creates a cookie / I snipped some code
setCookie(user.id);
}
// This is run on every request
private function $rememberMe() {
rememberMe("mySecretKey");
}
}
III. Store the key in a persistent scope so that calling it only once from the controller's init() is OK.
component
mixin="Controller"
{
public any function init() {
this.version = "1.0";
return this;
}
public void function rememberMe(string secretKey="rm_#application.applicationName#") {
application.secretKey = arguments.secretKey;
}
public void function setCookie(required string identifier) {
// This should now work
writeDump(var=application.secretKey, abort=true);
}
}

Rhino Mocks - Mock a method call to Service inside a property

I am trying to test that the property gets it's value from the return of a Service call, but I am having trouble mocking the service call.
Here is my property:
public ICountry Country
{
get
{
if (_country == null)
{
ICountryService countryService = new CountryService();
_country = countryService.GetCountryForCountryId(_address.CountryId);
}
return _country;
}
}
Here is my attempt at testing this:
[TestMethod]
public void Country_should_return_Country_from_CountryService()
{
const string countryId = "US";
_address.CountryId = countryId;
var address = MockRepository.GenerateStub<Address>(_address);
var country = MockRepository.GenerateMock<ICountry>();
var countryService = MockRepository.GenerateStub<ICountryService>();
countryService.Stub(x => x.GetCountryForCountryId(countryId)).IgnoreArguments().Return(country);
Assert.AreEqual(address.Country, country);
}
I keep getting an error because the real countryService is being called, not my mock. I am using MsTest and Rhino Mocks. What am I doing wrong?
You problem is that the property is directly constructing the dependency. Due to this the mock service is not getting called, the actual real CountryService implementation is getting called.
A way around this might be to utilize constructor injection of a CountryService factory (or the service itself) in the other objects (Address?) constructor. This way you could get your fake CountryService (the mock) to be returned and be the one called by the method
For example:
private ICountryService _countryService;
//constructor
public OuterObject(ICountryService countryService)
{
//maybe guard clause
_countryService = countryService;
}
public ICountry Country
{
get
{
if (_country == null)
{
_country = _countryService.GetCountryForCountryId(_address.CountryId);
}
return _country;
}
}
You would need to then pass the mocked ICountryService into the other objects constructor in your unit test