Implement assert_called_once_with() method with default parameters - unit-testing

def function(mocker):
mock_search = mocker.patch.object(Class, "mock_function", return_value={})
if Class.function("param1", "param2"):
mock_search.assert_called_once_with("param1", "param2", url=default_url)
elif Class.function("param1", "param2", url="URL"):
mock_search.assert_called_once_with("param1", "param2", url="URL")
Is there a way to compact the code. It should execute such that if Class.function("param1", "param2", url="URL") has url passed in Class.function method, the assert_called_once_with should be executed with the passed URL (if not) execute with default url.

Related

Symfony 3.2 - set environment variables in runtime [duplicate]

In my config.yml I have this:
parameters:
gitek.centro_por_defecto: 1
Now, I want to change this value from my controller using a form, like this:
public function seleccionAction(Request $request)
{
$entity = new Centro();
$form = $this->createForm(new SeleccionType(), $entity);
$centro = $this->container->getParameter('gitek.centro_por_defecto');
if ($this->getRequest()->getMethod() == 'POST') {
$form->bind($this->getRequest());
if ($form->isValid()) {
$miseleccion = $request->request->get('selecciontype');
$this->container->setParameter('gitek.centro_por_defecto', $miseleccion['nombre']);
// return $this->redirect($this->generateUrl('admin_centro'));
}
}
return $this->render('BackendBundle:Centro:seleccion.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
I´m getting Impossible to call set() on a frozen ParameterBag. error all the time.
Any help or clue?
You can't modify Container once it has been compiled, which is done before invoking the controller.
The DIC parameters are intended for configuration purposes - not a replacement for global variables. In addition it seems you want to persist some kind of permanent modification. In that case consider using session if it's a per-user modification or persisting it (e.g. into DB) if it's supposed to be application-wide.
If you need to modify DIC parameters or services, you can do so using a compiler pass. More info on how to write custom compiler passes can be found at:
http://symfony.com/doc/master/cookbook/service_container/compiler_passes.html
You can set $_ENV variables and get that after
putenv("VAR=1");
And to get
getenv("VAR");

Grails: pass a List from GSP to controller with remote link

So, in my method A in the controller ServicioComunitario I send this to the GSP:
tg = ServicioComunitario.findAll("from ServicioComunitario as b where "+query)
[servicioComunitarioInstanceList: tg, params: params]
Then in the GSP I call another method (generarDocDeReporte) of ServicioComunitarioController:
<g:set var="b" value="${'xls'}"/>
<g:set var="a" value="${'excel'}"/>
<g:set var="servicioLista" value="${servicioComunitarioInstanceList}"/>
<g:link controller="ServicioComunitario" action="generarDocDeReporte"
params="${[exportFormat:a, extesion:b, tg: servicioLista] }"
update="mainContent">Excel</g:link><br/>
Then, in the new method "generarDocDeReporte" I have:
println params.exportFormat+"-"+params.extesion
if(params.tg)
println "Not empty"
exportFormat and extension work as expected, but the params.tg doesn't seem to behave normal.
I am trying to use this new params.tg where it was a ServicioComunitario.list(params):
exportService.export(params.exportFormat, response.outputStream, ServicioComunitario.list(params), fields, labels, formatters, parameters)
And here is where I get the error:
exportService.export(params.exportFormat, response.outputStream, params.tg, fields, labels, formatters, parameters)
When I receive the params.tg, do I need to cast it? or what do you think is the error?
Thank you very much in advance
You can't just pass a list of instances like that in a link. You can however collect the ids into a list as a parameter and then use it to populate it later. For example:
<g:link controller="ServicioComunitario" action="generarDocDeReporte"
params="${[exportFormat:a, extesion:b, tgids: servicioLista.collect{it.id}.join(',')] }"
update="mainContent">Excel</g:link><br/>
And then in your controller where you need to get the list again:
def tg = ServicioComunitario.getAll(params?.tgids?.tokenize(","))
Also, you don't need to assign params to params when returning your model. parameters are already exposed in the GSP by convention.
[servicioComunitarioInstanceList: tg]

How to pass parameters via the selector/action?

Is there a way to pass parameters via the addTarget call as it calls another function?
I've also tried the sender method - but that seems to break as well. What's the correct way to pass the parameters without creating global variables?
#my_button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#my_button.frame = [[110,180],[100,37]]
#my_button.setTitle("Press Me", forState:UIControlStateNormal)
#my_button.setTitle("Impressive!", forState:UIControlStateHighlighted)
# events
newtext = "hello world"
#my_button.addTarget(self, action:'buttonIsPressed(newtext)', forControlEvents:UIControlEventTouchDown)
view.addSubview(#my_button)
def buttonIsPressed (passText)
message = "Button was pressed down - " + passText.to_s
NSLog(message)
end
Update:
OK, here's a method with an instance variable that worked.
#my_button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#my_button.frame = [[110,180],[100,37]]
#my_button.setTitle("Press Me", forState:UIControlStateNormal)
#my_button.setTitle("Impressive!", forState:UIControlStateHighlighted)
# events
#newtext = "hello world"
#my_button.addTarget(self, action:'buttonIsPressed', forControlEvents:UIControlEventTouchDown)
view.addSubview(#my_button)
def buttonIsPressed
message = "Button was pressed down - " + #newtext
NSLog(message)
end
The easiest way of attaching "parameters" to a rubymotion UIButton call is through the use of tags.
First set up a button with a tag attribute. This tag is the parameter you want to pass to the target function.
#button = UIButton.buttonWithType(UIButtonTypeRoundedRect)
#button.setTitle "MyButton", forState:UIControlStateNormal
#button.frame =[[0,0],[100,50]]
#button.tag = 1
#button.addTarget(self, action: "buttonClicked:", forControlEvents:UIControlEventTouchUpInside)
Now create a method that accepts sender as a parameter:
def buttonClicked(sender)
mytag = sender.tag
#Do Magical Stuff Here
end
Forewarning: As far as I know, the tag attribute only accepts integer values. You could get around this by putting your logic into the target function like this:
def buttonClicked(sender)
mytag = sender.tag
if mytag == 1
string = "Foo"
else
string = "Bar"
end
end
Initially I tried setting the action with action: :buttonClicked which worked but did not allow for using the sender method.
Yes, you usually create instance variables in your Controller class, and then just call methods on them from any method.
According to the documentation using setTitle is the general way to set a title of a UIButton instance. So you're doing it right.

Stubbing Custom TagLib method in Controller Unit Test

I have a method in a custom taglib like so:
def deleteAction = {attrs ->
def id = attrs['id']
def type = attrs['type']
def clazz = attrs['class']
def html = new MarkupBuilder(out)
html.span(class: "${clazz} ui-icon ui-icon-trash {id:'${id}'}")
}
I have a controller that uses this method and I'm trying to stub it out for a unit test, so I have the following:
def mockMyTagLib = mockFor(MyTagLib)
mockMyTagLib.demand.deleteAction(1) {id, type, clazz ->
def html = new MarkupBuilder(new StringWriter())
html.span(class: "${clazz} ui-icon ui-icon-trash {id:'${id}'}")
}
controller.metaClass.mn = mockMyTagLib.createMock()
But I keep getting the following:
No more calls to 'deleteAction'
expected at this point. End of
demands.
Am I doing something wrong here? Here is it's actual usage in the controller:
"${mn.deleteAction(id: it.id, type: 'bookProduct', 'class': 'del-book-product')}"
The following is from Testing - Reference Documentation
... You then specify the name of the
method that you want to mock with an
optional range as its argument. This
range determines how many times you
expect the method to be called, so if
the number of invocations falls
outside of that range (either too few
or too many) then an assertion error
will be thrown. If no range is
specified, a default of "1..1" is
assumed, i.e. that the method must be
called exactly once.
You've specified demand.deleteAction(1) which means that the method must be called once and only once.
Also, if you want, you can always set your mock to be loose by specifying it as the second parameter in mockFor (defaults to strict)
mockFor(class, loose = false)

Can a mocked domain "instance" be used in the controllers' show() method?

I am trying to pass a mocked domain instance called event to the controllers' show() method, but show() cannot find the Event in question and thus returns null.
Note that the following snippet is still work in progress.
def "trying to show an event containing malicous code"() {
given: "An event named with malicous code"
mockDomain(Event)
def event = Mock(Event)
event.title >> "<script type=\"text/javascript\">alert(\"XSS\");</script>"
event.id >> 1
// Do I have to actually create a full-blown event considering all
// constraints here?
when: "I try to show that event"
controller.params.id = 1
def result = controller.show()
then: "The resulting title will be encoded HTML"
result.eventInstance.title == event.title.encodeAsHTML()
}
This is the beginning of the controllers' show() method:
def show = {
def eventInstance = Event.get(params.id)
// The event exists
if (eventInstance) {
// some processing here
return [eventInstance: eventInstance, isSubscribed: sub ? true:false, sidebar: 'sidebar']
}
Is there a simple solution or will I have to actually create a full-blown event taking care of all constraints?
If I have to create a full event, where would I place the according method? (We're using a createEvent() method in BootStrap.groovy at the moment for initial setup, thus it wouldn't be DRY to repeat the function here).
Try mocking the Event object in the following way:
def event = new Event()
event.title = "<script type=\"text/javascript\">alert(\"XSS\");</script>"
event.id = 1 // optional
mockDomain Event, [event]
Unless you add an instance of event to the mockDomain call, you won't be able to retrieve it with get