Is it possible to mock a closure using GroovyMock? - grails

So I have a utility class for validation with static methods like the following:
static validateX = { x ->
// some business logc
}
Now, I use this static closure in my command objects for custom validation:
class TestCommand {
String x
static constraints = {
x(validator: Utility.validateX)
}
}
The problem arises when I try to mock this custom validator during my unit tests. I have tried a bunch of things as seen below:
GroovyMock(Utility)
Utility.validateX(someVal) >> true
Utility.validateX.call(someVal) >> true
Utility.validateX >> { def x -> true }
But none of these work!
I have found a work around where I change static utility closure to a method. When I change it to a normal method, GroovyMock seems to work fine. But I would rather not do this since I'll then I have to use the ampersand symbol wherever I reference the method, and I can see it confusing others on my team.
So basically, my question is how do I mock a static closure in my unit tests?

Related

Dart extension: don't access members with 'this' unless avoiding shadowing

I'm learning to use the new Dart extension methods.
I'm doing this:
extension StringInsersion on StringBuffer {
void insertCharCodeAtStart(int codeUnit) {
final end = this.toString();
this.clear();
this.writeCharCode(codeUnit);
this.write(end);
}
int codeUnitAt(int index) {
return this.toString().codeUnitAt(index);
}
}
So that I can do something like this:
myStringBuffer.insertCharCodeAtStart(0x0020);
int value = myStringBuffer.codeUnitAt(2);
However, I get the following lint warning:
Don't access members with this unless avoiding shadowing.
Should I be doing something different?
The warning you received means the following:
There is no need to reference the current instance using keyword this. Everything will work without reference to the current instance because the static extension method itself acts as an instance method of extensible type.
Simply put, just remove the reference to the current instance from your code.
From this:
final end = this.toString();
To this:
final end = toString();
It's a style thing, based on Dart's guide. There are examples in https://dart-lang.github.io/linter/lints/unnecessary_this.html.
You can find more about style in https://dart.dev/guides/language/effective-dart/style.
I turn off this rule globally by changing "analysis_options.yaml"
include: package:flutter_lints/flutter.yaml
linter:
rules:
unnecessary_this: false

How do I create a "getter" for my modules (How do you instantiate a Module Object using a Navigator?)

I am trying to make it so that all of my page and module references can autocomplete in intellij.
Due to some sort of bug I am unable to do this like one normally would. (see here for more details: How to have geb static content recognized form test script )
In order to work around the above mentioned bug. I opted to create "getters" for all of my static content.
for example:
The Page:
class MyPage extends Page{
static content = {
tab {$(By.xpath("somexpath")}
}
Navigator tab(){
return tab
}
}
The Script:
//imagine we are in the middle of a feature method here
def test = at MyPage
test.tab().click()
So all of the above code works as I expect it to, and I want to redo my pages like this so that I can have autocomplete from the script side. Problems occur when I try to use this same technique for modules.
For example:
class MyPage extends Page{
static content = {
mod {module(new MyModule())}
}
MyModule mod(){
return mod
}
}
If I try and access mod from the script like so
//imagine we are in the middle of a feature method here
def test = at MyPage
test.mod().someModContentMaybe().click()
I get the following error:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'MyPage' -> mod: 'MyModule' with class 'geb.content.TemplateDerivedPageContent' to class 'MyModule'
If I try to do the following in the page object:
class MyPage extends Page{
static content = {
mod {module(new MyModule())}
}
MyModule mod(){
return new MyModule()
}
}
I get the following error when attempting to access the module from the script:
geb.error.ModuleInstanceNotInitializedException: Instance of module class MyModule has not been initialized. Please pass it to Navigable.module() or Navigator.module() before using it.
I guess it wants me to take an instantiated Navigator Object and and to call module(MyModule) but I am not sure how this works or how one would decide which Navigator Object to call module from.
All in all, I just want to be able to autocomplete module Names and static content from my scripts.
The Book of Geb's section about modules answers your question. You should not manually call the module's constructor, but instead instead use the syntax described right at the beginning of the chapter. This solution gets rid of the exception and also solves the code completion problem for me:
static content = {
mod { module MyModule }
}
Now that the exception is gone here is how to add the getter you asked for:
def myModule() { mod }
You're getting a GroovyCastException when returning content that contains a module from a method whose return type is a class which extends geb.Module because navigators and modules returned from content definitions get wrapped in geb.content.TemplateDerivedPageContent.
You can unwrap them using the as keyword as explained in the manual section about unwrapping modules returned from the content DSL. So, for one of your examples it would look like this:
MyModule mod(){
mod as MyModule
}
I think the problem is you content block. Modules are defined via Navigators' module method:
static content = {
mod { $("div.module").module(MyModule)
}
So no constructor calling required.

How can I test a private or fileprivate function in project

I want to write some unit testing code for a manager class, the function I would write for is using some small private functions. I will prepare a lot if I testing the public function, so I want to test those private functions. But in test target I can't call the private function directly.
So I wanna ask, is there's a way to test them without change them from private to internal or public?
So I wanna ask, is there's a way to test them without change them from private to internal or public?
Add an internal function that does nothing but call the private function. Probably it's best to do it in an extension:
class Foo
{
fileprivate func myPrivateFunction(p: Int) { ... }
}
extension Foo
{
internal func testMyPrivateFunction(p: Int)
{
myPrivateFunc(p: p)
}
}
You can probably find a way of using conditional compilation to omit the extension for release builds e.g.
#if DEBUG
extension Foo
{
internal func testMyPrivateFunction(p: Int)
{
myPrivateFunc(p: p)
}
}
#endif
Not tested the conditional thing to see if it works, it's borrowed from here https://ericasadun.com/2018/04/18/forcing-compiler-errors-in-swift/
Sadly no. There isn't a "VisibleForTesting" tag in Swift as there is in java.
However you can define a protocol which your manager class then implements including only the methods you want to test.
For example if your manager has a function called createViewModel that calls several private methods testing that the viewModel created matches that of what we expect we have implicitly tested the private methods work. You can set up your manager with different initial conditions to test all varieties and edge cases
I think you are looking for #testable imports. From Apple's documentation:
When you add the #testable attribute to an import statement for a
module compiled with testing enabled, you activate the elevated access
for that module in that scope. Classes and class members marked as
internal or public behave as if they were marked open. Other entities
marked as internal act as if they were declared public.
Interfaces are the solution.
This solution is a bit more complicated than the others, but can help you for multiple purposes, like uncoupling modules on your app.
Let's say you have a class Foo which has an object of type Bar, and you need to call doStuff().
Create a Protocol for Bar. So Foo is decoupled from Bar and becomes fully testable without exposing its content to Foo. Something like this:
protocol BarProtocol {
func doStuff()
}
class Bar:BarProtocol {
func doStuff() {
print("Hello world")
}
}
class Foo {
var bar:BarProtocol
init() {
self.bar = Bar()
self.bar.doStuff()
}
}

Using Spock to stub both Gorm and other methods in a Grails domain class

Sorry if this is a newbie question but I would really appreciate any insights the community could offer with regard to a problem I am having with stubbing the following method which I have in a Grails service, LocationService.
Location locate(String target, String locator, Application app, boolean sync = true) {
if (!target) throw new IllegalArgumentException("Illegal value for msid: " + target)
def locRequest = Request.create(target, Type.LOCATE)
if (!locRequest.save()) {
return Location.error(target, "Error persisting location request")
}
locationSource.locateTarget(target, locator, app, sync)
}
I have a domain class, Request, that as well as the default GORM methods also has some extra domain methods, eg. the create() method below
#EqualsAndHashCode
class Request {
String reference
String msid
Type type
Status status
Destination destination
DateTime dateCreated
DateTime dateCompleted
static create(String msid, Type type, Destination destination = Destination.DEFAULT) {
new Request(reference: reference(type), type: type, status: Status.INITIATED, dateCreated: new DateTime())
}
Finally, I have a Spock specification. I need to mock both the default GORM methods but also some stub some extra domain logic, eg, a static create method, in order to return a valid object to be persisted in the code under test.
Ideally, I would use Spock mocks but I can't use them here as according to the post below from Peter N, they need to be injected into the caller and in this case the Request (which I am trying to mock), is created as a local variable in the locate method in LocationService:
https://groups.google.com/forum/?fromgroups=#!topic/spockframework/JemiKvUiBdo
Nor can I use the Grails 2.x #Mock annotation as, although this will mock the GORM methods, I am unsure if i can mock/stub the additional static create() method from the Request class.
Hence, finally, I have been trying to use the Groovy StubFor / MockFor methods to do this as I believe that these will be used in the call to the test method by wrapping it in a use closure (as below).
Here is the test spec:
#TestFor(LocationService)
// #Mock(Request)
class LocationServiceSpec extends Specification {
#Shared app = "TEST_APP"
#Shared target = "123"
#Shared locator = "999"
def locationService = new LocationService()
LocationSource locationSource = Mock()
def "locating a valid target should default to locating a target synchronously"() {
given:
def stub = new StubFor(Request)
stub.demand.create { target, type -> new Request(msid: target, type: type) }
stub.demand.save { true }
1 * locationSource.locateTarget(target, locator, app, SYNC) >> { Location.create(target, point, cellId, lac) }
def location
when:
stub.use {
location = locationService.locate(target, locator, app)
}
then:
location
}
However, when I run the test, although the stubbed create method returns my Request stub object, I get a failure on the stubbed save method:
groovy.lang.MissingMethodException: No signature of method: com.domain.Request.save() is applicable for argument types: () values: []
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), last(), any()
Could anybody please point out what I am doing wrong here or suggest the best approach to solve my particular case if needing to stub additional methods as well as GORM methods of a domain class that I can't inject directly into the code under test?
Thank you in advance,
Patrick
I believe you should be able to use Grails' #Mock annotation like you mentioned for the GORM methods, and then you will need to manually mock the static methods:
#TestFor(LocationService)
#Mock(Request)// This will mock the GORM methods, as you suggested
class LocationServiceSpec extends Specification {
...
void setup() {
Request.metaClass.static.create = { String msid, Type type, Destination destination = Destination.DEFAULT ->
//Some logic here
}
}
...
When using the #Mock annotation, Grails will mock the default methods (save/get/dynamic finders), but it doesn't do anything to any additional methods you may have added, so you need to manually mock those.

Testing Grails taglibs that call other taglibs

Say I've got two taglibs, Foo which does something specific for a particular part of my application, and Util which is shared across the whole thing. I want to do something like this:
class UtilTagLib {
def utilTag = { attrs ->
...
}
}
class FooTagLib {
def fooTag = {
...
out << g.utilTag(att1: "att1", att2: "att2")
...
}
}
However, when I do this, and try to run my unit test for fooTag(), I get:
groovy.lang.MissingMethodException: No signature of method: org.codehaus.groovy.grails.web.pages.GroovyPage.utilTag() is applicable for argument types: (java.util.LinkedHashMap) values: [[att1:att1, att2:att2]]
I tried giving UtilTagLib its own namespace
static namespace = "util"
and changing the call to
out << util.utilTag(...)
but this just gets me
groovy.lang.MissingPropertyException: No such property: util for class: org.example.FooTagLib
Possibly also of note: In the log, I see:
WARN - Bean named 'groovyPagesUriService' is missing.
Obviously, UtilTagLib isn't getting created and injected correctly. How can I fix this?
Solution: add the call
mockTagLib UtilTagLib
to the setUp() (or #Before) method of the test case. This is a method on GroovyPageUnitTestMixin that, somewhat counterintuitively, instantiates the specified tag library -- the real one, not a mock -- and wires it into the Grails application context. It's used internally to set up the actual taglib under test (in this case FooTagLib), but it also works to set up additional collaborator tag libs.
Note that this isn't perfect, since it makes it more of an integration test than a pure unit test -- ideally we would be using a mock UtilTagLib and just testing the interaction.
One approach would be to refactor the line:
out << g.utilTag(att1: "att1", att2: "att2")
in to its own method, say "renderUtilTag(...)", then mock that out in the unit test, e.g.:
FooTagLib.metaClass.renderUtilTag = { /* something */ }
That way you're testing the functionality of FooTagLib only in the unit test, with no dependency on UtilTagLib.

Resources