I have a simple groovy script in which I call a method named cron(String cronExpression) from ItemTriggerContext, like:
job('george') {
triggers {
cron('5 4 4 4 4')
}
}
I want to allow the cron method to be called only if some of my validations of the input String pass.
if(myValidationsOfCronExpr are ok) {
call the cron method with said parameter
}
else {
return null
}
This is why I need to intercept all calls to the cron() method from my project.
Already tried http://mrhaki.blogspot.com/2009/11/groovy-goodness-intercept-methods-with.html and https://www.webucator.com/how-to/how-use-the-intercept-cache-invoke-design-pattern-groovy.cfm but they seem applicable only on your own classes.
Any help is much appreciated!
Related
I have a private service method that is called from create and update methods in the same service. Normally we do not write Unit Test directly for the private method and I write the case in the method that calls this service method.
At this stage, I am confused that; I write all the test cases for the private method in the tests for create method.
1. In this scene, should I omit the same case for the private method when I write test method for the update method? Because in this case it seems to be writing redundant tests for the same case (calling it from create + calling it again from update method).
2. On the other hand, I am also thinking of that if I remove create or update method in the future, then calculate method tests will be removed. In this case, it may be better to write test cases related to calculate method in both of create and update methods.
Any idea regarding to this issue?
Here is a sample code if you need to explain something based on this scenario:
public void create(EmployeeRequest request) {
// code omitted
calculate();
}
public void update(UUID uuid, EmployeeRequest request) {
// code omitted
calculate();
}
private void calculate() {
// code omitted
}
Is there a way in JAVA to listen for a specific annotation that is being called, and run a method before / after the annotation, specifically in a Cucumber / JUnit framework? For example, when the following code is being called due to step in your feature file ("Then something happens"):
#Then("something happens")
public void somethingHappens(){
// run code in method
}
That before / after the somethingHappens() method is called, another method is called like:
public void doSomethingElseBeforeAnnotation(){
// run code in method
}
There is the #BeforeStep and #AfterStep in the Cucumber framework, but i want to be able to run the method only at, for example, the "#Then" annotations. So actually, i neeed something like a #BeforeThen :)
I am writing a unit test for a FizzConfigurator class that looks like:
public class FizzConfigurator {
public void doFoo(String msg) {
doWidget(msg, Config.ALWAYS);
}
public void doBar(String msg) {
doWidget(msg, Config.NEVER);
}
public void doBuzz(String msg) {
doWidget(msg, Config.SOMETIMES);
}
public void doWidget(String msg, Config cfg) {
// Does a bunch of stuff and hits a database.
}
}
I'd like to write a simple unit test that stubs the doWidget(String,Config) method (so that it doesn't actually fire and hit the database), but that allows me to verify that calling doBuzz(String) ends up executing doWidget. Mockito seems like the right tool for the job here.
public class FizzConfiguratorTest {
#Test
public void callingDoBuzzAlsoCallsDoWidget() {
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
Mockito.when(fixture.doWidget(Mockito.anyString(), Config.ALWAYS)).
thenThrow(new RuntimeException());
try {
fixture.doBuzz("This should throw.");
// We should never get here. Calling doBuzz should invoke our
// stubbed doWidget, which throws an exception.
Assert.fail();
} catch(RuntimeException rte) {
return; // Test passed.
}
}
}
This seems like a good gameplan (to me at least). But when I actually go to code it up, I get the following compiler error on the 2nd line inside the test method (the Mockito.when(...) line:
The method when(T) in the type Mockito is not applicable for the arguments (void)
I see that Mockito can't mock a method that returns void. So I ask:
Am I approaching this test setup correctly? Or is there a better, Mockito-recommended, way of testing that doBuzz calls doWidget under the hood? And
What can I do about mocking/stubbing doWidget as it is the most critical method of my entire FizzConfigurator class?
I wouldn't use exceptions to test that, but verifications. And another problem is that you can't use when() with methods returning void.
Here's how I would do it:
FizzConfigurator fixture = Mockito.spy(new FizzConfigurator());
doNothing().when(fixture).doWidget(Mockito.anyString(), Mockito.<Config>any()));
fixture.doBuzz("some string");
Mockito.verify(fixture).doWidget("some string", Config.SOMETIMES);
This isn't a direct answer to the question, but I ran across it when trying to troubleshoot my problem and haven't since found a more relevant question.
If you're trying to stub/mock an object marked as Spy, Mockito only picks up the stubs if they're created using the do...when convention as hinted at by JB Nizet:
doReturn(Set.of(...)).when(mySpy).getSomething(...);
It wasn't being picked up by:
when(mySpy.getSomething(...)).thenReturn(Set.of(...));
Which matches the comment in MockHandlerImpl::handle:
// stubbing voids with doThrow() or doAnswer() style
This is a clear sign that doWidget method should belong to another class which FizzConfigurator would depend on.
In your test, this new dependency would be a mock, and you could easily verify if its method was called with verify.
In my case, for the method I was trying to stub, I was passing in incorrect matchers.
My method signature (for the super class method I was trying to stub): String, Object.
I was passing in:
myMethod("string", Mockito.nullable(ClassType.class)) and getting:
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
When using a matcher in another parameter, we also need to use one for the string:
myMethod(eq("string"), Mockito.nullable(ClassType.class))
Hope this helps!
I am developing my project on spring+hibernate+annotations. I need to apply some set of validations on the data.
presently the code seems like this.
public class SomeClass{
boolean error = false;
if(!error){
check condition1
if(fails) {
error = true;
}
}
if(!error){
check condition2
if(fails) {
error = true;
}
}
if(!error){
check condition3
if(fails) {
error = true;
}
}
// similarly i have 5 to 10 validations.
}
Is there any design pattern that can replace the above scenario.
Thanks.
spring offers validation classes, see org.springframework.validation
the reference supplies a full tutorial of the way spring handles validation errors. http://static.springsource.org/spring/docs/2.5.x/reference/validation.html
On my current project we went a bit further, we crated a ValidationTemplate class that is abstract. We have 2 methods, a validate method that calls an abstract method with a List<Error>
When we want to validate we can just create an anonymous instance of that abstract class and implement the doInValidation method. This allows you to
new ValidationTemplate(){
doInValidation(List<Error> errors){
if(!condition) {
errors.add(new Error("reason");
}
}.validate();
you can implement the validation method as you want, you could throw an exception or return the list with errors if you want a more elegant result.
Unfortunately I cannot post the exact source instead of this piece of pseudo code.
You should be looking Hibernate Validator.
I'd like to test that every method with a known prefix in a specific class is called during a particular test.
I can't work out a way to use mockito to stub out a method or how to verify that method has been called when the method name is not known until runtime.
The code below shows how I can get the methods I'd like to stub:
Method[] methodArr = customValidation.getClass().getDeclaredMethods();
loop: for (Method method : methodArr) {
if (method.getName().startsWith("validate")) {
// then stub out this method and check whether it gets called
// after we run some code
}
}
The question is, how can I stub them without know the method names until runtime?
Has anyone done anything like this before or have a good idea of how it can be done?
Many Thanks
This does not appear to be possible as of now. There is an unresolved enhancement request
For anyone who's interested, the solution I used was to use regular mocking to stub my methods:
UserBeanValidation userBeanValidation = Mockito.mock(UserBeanValidation.class);
Mockito.when(userBeanValidation.validateUserId(Mockito.anyString())).thenReturn(validationError);
I verified they were called once and incremented a count whenever one of the stubbed methods was executed. This count could be compared with a count of methods with a specific prefix to ensure all expected methods were called:
int totalMethodCount= 0;
Method[] methodArr = customValidation.getClass().getDeclaredMethods();
loop: for (Method method : methodArr) {
if (method.getName().startsWith("validate")) {
totalMethodCount++;
}
}
Assert.assertEquals(totalMethodCount, calledMethodCount);
This way I can be sure that all my methods are called... now to find out if they do what they're supposed to.