I have started working on a BDD project using JBehave. I need to build a sequence of methods to be called based on the steps "Given", "When" and finally execute them in "Then". A sample would be like
Given a user logins as a premium user
When he adds an item to the cart
Then he gets a special discount
For the above scenario, I would have to build method call sequence based on "Given" / "When" and then execute the same in "Then"
E.g.
List<Executable> sequenceList
#Given
public void execGiven()
{
A a = new A();
a.call1()
a.call2()
B b = new B();
b.call3();
}
#When
public void execWhen(){
C c = new C();
c.call4();
//...few more methods
#Then
public void execThen(){
//Add some methods to the list of executables
D d = new D();
d.call5();
Assert if everything successful
}
The problem I am facing is that the framework we are using(in built and in use) cannot be used to partially execute the method call sequences in each Step of a story. Rather, I have to execute them as a whole sequence( from a.call1 to d.call5).Also another issue is that I dont want to hardcode the method calls for each step instead call them based on some config at runtime.
My Approach.
Instead of running these methods (a.call1 , a.call2) in each step, add them to a list of Methods and execute them in "Then" using reflections. Also use annotations like
#Sequence(step="Login" , sequenceId=1) for each method so that at runtime I can build a list of calls to be made.
What would be a good approach considering that any change in the method call sequence is less painful to change. I had few approaches in mind
Use annotations to wire the sequence
Use xml to wire the sequence
Use a text file to mention the sequence(almost same as above)
Is there any better approach to build the graph in the runtime and execute the sequence? Also any drawbacks of the same?
Thank You
Related
I'm trying to test the method on mocked object getting called in the expected order or not. Below is the simplified example:
#Test
public void test() {
List<String> mockedList = Mockito.mock(List.class);
for (int i = 0; i < 5; i++) {
mockedList.add("a");
mockedList.add("b");
mockedList.add("c");
}
// I want only this to pass.
InOrder inOrder1 = Mockito.inOrder(mockedList);
inOrder1.verify(mockedList).add("a");
inOrder1.verify(mockedList).add("b");
inOrder1.verify(mockedList).add("c");
// I want this to fail.
InOrder inOrder2 = Mockito.inOrder(mockedList);
inOrder2.verify(mockedList).add("c");
inOrder2.verify(mockedList).add("b");
inOrder2.verify(mockedList).add("a");
}
Although the verifying order (c -> b -> a) is different from the invocation order (a -> b -> c), this test passes. This is because Mockito verifies if method2 called anywhere AFTER method1, but not immediately (i.e., no other method called in between). As I'm adding elements multiple times, this is very much possible. Which means, Mockito InOrder passes for b -> a -> c -> a -> c -> b -> c -> b -> a ...
But I want this to fail, and make sure the order is always a -> b -> c -> a -> b -> c -> a -> b -> c ...
Update: Proper way to verify is to verify the order same number of iterations (summary of accepted answer):
for (int i = 0; i < 5; i++) {
inOrder1.verify(mockedList).add("a");
inOrder1.verify(mockedList).add("b");
inOrder1.verify(mockedList).add("c");
}
// fail the test if we missed to verify any other invocations
inOrder1.verifyNoMoreInteractions();
The thing is that you need to add
inOrder.verifyNoMoreInteractions();
With your loop you generate calls like
add(a)
add(b)
add(c)
add(a)
add(b)
add(c)
When you then check
inOrder.verify(mockedList).add("b");
inOrder.verify(mockedList).add("c");
inOrder.verify(mockedList).add("a");
It matches the calls (add(b), add(c), add(a)). The other calls are not checked.
add(a)
add(b)
add(c)
add(a)
add(b)
add(c)
So I think you have to options:
1) verify all calls a, b, c, a, b, c
2) verify that no more interactions happen to your mock
BTW if you change the verification to
inOrder.verify(mockedList).add("c");
inOrder.verify(mockedList).add("b");
inOrder.verify(mockedList).add("a");
it will fail as it does not match the calls :-)
A non answer here: you are going down the wrong path (at least for the given example):
Meaning: when you create an "API", you want to achieve "easy to use, hard to mis-use". An API that requires methods to be called in a certain order doesn't achieve that. Thus: feeling the need to check for order programmatically could be an indication that you are doing "the wrong thing". You should rather design an API that "does the right thing" instead of expecting users of your code to do that for you.
Beyond that: when you are testing lists, you absolutely do not want to use mocking in the first place.
You want to make sure that elements get added to a list in a specific order? Then a simple
assertThat(actualList, is(expectedList));
is the one and only thing your test should check for!
Meaning: instead of testing an implementation detail (add() gets called with this and that parameter, in this and that order), you simply check for the observable outcome of that operation. You don't care in which order things get added, and maybe re-setted and updated, you only care for the final result!
Given the comment by the OP: when you have to process certain calls/objects "in order", then you should design an interface that allows you communicate that intent. You are only testing your intent via unit tests. That is of course a good start, but not sufficient!
Basically, there are two concepts that could work for you:
Sequence numbers: when objects come in sequentially, and order matters, then each object should receive a unique (ideally ascending) sequence number. And then each step that processes elements can simply remember the last sequence number that was processed, and if a lower one comes in, you throw an exception.
Sequences of "commands". The OP wants to make sure that method calls happen in order. That is simply not a helpful abstraction. Instead: one could create a Command class (that executes "something"), and then create different subclasses for each required activity. And then your processor simply creates a List<Command>. And now testing boils down to: generating such a sequence, and checking that each entry is of a given type.
Simplifying a bit, our system has two parts. "Our" part, which in turn uses an lower level part implemented by another team (in the same codebase). We have a fairly complicated functional test setup, where we wrap the entry points to the lower level in spy objects. In positive tests we use the real implementation of that level, but we mock calls that should fail with some predefined error.
Now I am trying to add support for more complicated scenarios, where I would like to add an artificial delay for the calls made to the underlying level (on a fake clock obviously). To do this I would like to define a mock that would (1) Call the real implementation (2) Get the resulting Future object that is returned and combine it with a custom function that would inject the delay accordingly. So Ideally I would like to have something like:
doAnswer(invocationOnMock ->
{
result = call real method on mySpy;
return Futures.combile(result, myFunction);
}).when(mySpy).myMethod();
How can I achieve it?
As for me the easiest way it's just to save the link to the read object when you initialize your Spy object:
Foo realFoo = new Foo();
Foo spyFoo = Mockito.spy(realFoo);
Now you can stub it like this:
doAnswer(invocation -> realFoo.getSome() + "spyMethod").when(spyFoo).getSome();
One more way is to call invocation.callRealMethod():
doAnswer(invocation -> invocation.callRealMethod() + "spyMethod").when(spyFoo).getSome();
But in this case you may need to cast the return value as long as invocation.callRealMethod() returns Object.
Situation: I have multiple states of the same object represented by different instances (which are made using a deep-copy). Now I want to make sure that, no matter which of these grouped instances is accessed, all operations that perform modifications are redirected onto the youngest of these instances[1].
Example:[2]
//Let's create an object
MyObject mObj = new MyObject(...);
//Let's create a list of past states
List<MyObject> pastStates = new ArrayList<MyObject>();
//doing some operations on mObj ....
mObj.modify(...);
//done modifying mObj, now let's save it's state and then create a copy to begin again
pastStates.add(mObj.copy());
//more of this...
mObj.modify(...);
pastStates.add(mObj.copy());
//let's compare some old states for whatever reason (e.g. part of an algorithm)
compare(MyObject o1, MyObject o2) {
if(o1.getA() == o2.getA()) {
o2.modify(...); //wait, we modified an old state...
}
Now this is a rather obvious example and probably a classic case of programmer's fault. They modified something that is clearly advertised as being a past state whatsoever... But say we still want to be nice and try to help and thus intercept the method call and perform it on the correct instance namely the youngest/master instance.[3]
Question: Is there a way to do this with standard java?
Bonus: Is there a way that doesn't have a horrible impact on performance?
Background: I'm experimenting around with different ways to make a library/engine, I'm writing for fun, harder to misuse by the enduser. As I will need these states internally anyways (snapshots in time for certain background functionalities), I would like to make them available to the enduser as well so they can profit of my statekeeping, e.g. for use in analytical algorithms.
[1] There can be multiple groups of instances of an object that are not related to each other; relation will presumably be kept by a one way link to the youngest instance which simply won't ever change.
[2] This code is meant as an example, it is clear that this mistake could be prevented by the enduser paying more attention when writing code.
[3] Now an easy way to prevent modification is to wrap the object into an immutable version which throws exception when trying to modify it > but we do not write this object ourselves and don't want to force it upon the enduser to write two versions of their own object if we don't have to...
I would probably create two classes: an "inner" one which is immutable and an "outer" one that maintains a list of inners. (Note: I don't mean inner classes in the JLS sense, just an object that is fully controlled by its wrapper.)
Something like this:
public final class Outer {
private final List<Inner> history = new ArrayList<>(); //history is inverted for brevity, 0 is the latest one
public Outer(int x) {
this.history.add(new Inner(x));
}
public void add(int x) {
history.add( 0, new Inner(history.get(0).x+x);
}
public Inner current() {
return history.get(0);
}
public static final class Inner {
private final int x;
private Inner(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
}
With this setup clients can only instantiate Outer, can only mutate Outer but have access to a read-only copy of all the past states. There is no way to accidentally modify a past state. There is no need for separate grouping logic either because each instance of Outer naturally only records its own history.
Method interception can be done with AOP by using an around advice. AspectJ is a good tool for solving such problems. The impact on performance should also be no problem.
In an around advice in most cases you call proceed to execute the target method on the target object, but you can also prevent the method execution and instead do a method call on another object.
Yes, it is possible using bytecode modification.
Actually, if it was done by AspectJ or other library, it would be implemented using proxies or byte code modification. But I'm not sure that this specific task is possible with Aspect programming libraries API.
You can find working example for your task in this repo.
This test from repository works fine:
//Let's create an object
MyObject mObj = new MyObject();
MyObjectActiveRepository.INSTANCE.putToGroup(mObj, "group1");
MyObjectActiveRepository.INSTANCE.registerActiveForItsGroup(mObj);
//Let's create a list of past states
List<MyObject> pastStates = new ArrayList<MyObject>();
//doing some operations on mObj ....
mObj.modify("state1");
//done modifying mObj, now let's save it's state and then create a copy to begin again
pastStates.add(mObj.copy());
//more of this...
mObj.modify("state2");
pastStates.add(mObj.copy());
mObj.modify("state3");
assertEquals("state1", pastStates.get(0).getState());
assertEquals("state2", pastStates.get(1).getState());
assertEquals("state3", mObj.getState());
pastStates.get(0).modify("stateNew");
assertEquals("state1", pastStates.get(0).getState());
assertEquals("state2", pastStates.get(1).getState());
assertEquals("stateNew", mObj.getState());
Shortly -
I use ByteBuddy (Bytecode generation and modification tool) to redefine class bytecode before it has been load to:
remove final from class (if we have)
add field to save MyObject's "group" to address your (1) note
intercept call to copy(we need to copy "group" field additionally) and modify (to retarget call)
replace class code in classloader
TypePool typePool = TypePool.Default.ofClassPath();
new ByteBuddy()
.rebase(typePool.describe("MyObject").resolve(), ClassFileLocator.ForClassLoader.ofClassPath())
.modifiers(TypeManifestation.PLAIN) //our class can be final and we have no access to it - so remove final
.defineField("group", String.class, Visibility.PUBLIC)
.method(named("modify")).intercept(MethodDelegation.to(typePool.describe("Interceptors").resolve()))
.method(named("copy")).intercept(MethodDelegation.to(typePool.describe("Interceptors").resolve()))
.make()
.load(InterceptorsInitializer.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION);
Implemented MyObjectActiveRepository which contains information about active object for group and "group" field related functionality.Interceptors with simple copy redefinition which add "group" setting and modify, which makes our retargeting.
I think it should be lite code, the most expensive part is reflection call to setter on group-to-object assignment after object creation (this part can be improved; if we use ByteBuddy - we can replace reflection with implementing new interface with getGroup() and setGroup(String) methods during byte code generation with delegating them to FieldAccessor.ofField("group"), so we will have fine effective invokevirtual thru interface). modify() should have near the same performance, because it doesn't use reflection, only fully generated bytecode. I didn't make any benchmarking.
Consider a class that uses an external jar. The class processes objects of type D, which are obtained via objects A, B, and C, all of which external objects from the jar.
class DProcessor() {
public void process(PoolOfA pool) {
A a = pool.borrowObject()
...
B b = a.getB()
C c = b.getC()
for (D d : c.getAllDs()) {
// Do something meaningful with d
}
}
}
How do I Unit test process(PoolOfA pool)?
My best shot so far is writing mocks for all external classes:
PoolOfA pool = mock(PoolOfA.class);
A a = mock(A.class);
B b = mock(B.class);
C c = mock(C.class);
D d1 = mock(D.class);
D d2 = mock(D.class);
D d3 = mock(D.class);
D d4 = mock(D.class);
List listOfDs = new ArrayList<D>();
listOfDs.add(d1);
listOfDs.add(d2);
listOfDs.add(d3);
listOfDs.add(d4);
// Set specific behaviour for each d
when(pool.borrowObject()).thenReturn(a);
when(b.getC()).thenReturn(a);
when(c.getAllDs()).thenReturn(d);
when(b.getC()).thenReturn(c);
when(c.getAllDs()).thenReturn(listOfDs);
This seems cumbersome and inelegant. Is there a better way?
Better way is to rewrite the method, of course. But if you cannot do it for some reason, mockito offers great feature called 'deep stubs'. Check out the docs.
What process really does, is process some Ds in the loop. I would first make it clear by changing the signature:
public void process(Collection<D> allDs)
Now you can test that more easily by mocking D only.
That method can either be public if it can replace the existing one or package private for example if you don't want to expose it. In that latter case, you might still want to test that the other process method (the one that takes a poolOfA) properly extract the Ds. But that means that process(PoolOfA) needs to know a lot about the poolOfA which does not seem right.
This is one of the ideas promoted by this "Guide to writing testable code" which I think contains interesting concepts. What you mention would probably fall into the "Digging into Collaborators" section.
I would suggest a small redesign of the process method: It is currently responsible for doing two things: Extracting an Iterable of D's from the internals of the input and processing them.
So actually, you method, although declaring that it is expecting an input of type PoolOfA, is absolutely not interested in this object. It wants what's inside. I wold declare the method as taking an Iterable and pass the responsibility to the caller to give it the correct input. This will clarify the intention of the method and make it easier to test.
You may say: "this is not a real solution, this is just moving the problem to another location!
now I need to test the calling method!"
Well, yes and no. First, remember that you do not have to UT everything, just for the sake of coverage. You should focus your UT efforts on algorithmic pieces of code, it is OK to skip trivial object interactions.
If you insist, you can use more powerful mocking libraries like PowerMock in order to mock only past of your class, but this is a discussion for a different Question.
I would like to use wait(int) as the signature of a method in a fluent API (used for http://www.jooq.org). The goal is to be able to construct SQL queries like this example:
SELECT * FROM T_AUTHOR
WHERE ROWNUM <= 1
FOR UPDATE OF FIRST_NAME, LAST_NAME
WAIT 5
The full FOR UPDATE clause syntax specification (at least for Oracle) can be seen here:
FOR UPDATE [ OF [ [ schema. ] { table | view } . ] column
[, [ [ schema. ] { table | view } . ] column]...]
[ { NOWAIT | WAIT integer | SKIP LOCKED } ]
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/img_text/for_update_clause.htm
With jOOQ, I really want to stay close to the SQL syntax. So I'd like to be able to model the above SQL clause with the jOOQ fluent API like this:
Result<Record> result = create.select()
.from(T_AUTHOR)
.limit(1)
.forUpdate()
.of(FIRST_NAME, LAST_NAME)
.wait(5) // Here's the issue
.fetch();
The fetch method is used to render the API's underlying object as SQL and run the SQL statement against an Oracle (or any other) database. The above can be legally specified in an interface:
/**
* A type that models a "step" in the creation of a query using the fluent API
*/
public interface SelectForUpdateWaitStep extends SelectFinalStep {
// [...]
/**
* Add a "FOR UPDATE .. WAIT n" clause to the query
*/
SelectFinalStep wait(int seconds);
// [...]
}
I have some doubts about this, though, because there is a risk of collision with another method:
public class Object {
// [...]
public final native void wait(long timeout) throws InterruptedException;
// [...]
}
Thanks to method-overloading (int vs. long arguments), I can actually do this. But I'm afraid it might confuse my users and lead to mistakes. So this would be wrong:
.forUpdate()
.of(FIRST_NAME, LAST_NAME)
.wait((long) 5) // This doesn't make sense
.fetch(); // This doesn't compile
So my questions are:
Can I somehow prevent calling/accessing Object.wait(long) altoghether? I don't think so because it's declared final but maybe someone knows a compiler-trick, or something else?
Do you have a better idea for my API design apart from just renaming the method to something silly like doWait(int) or WAIT(int)?
You might try using a waitFor method instead, which specifies both a time and a "condition" to wait for. The implementation detail would be hidden, but one possible implementation would be to try your action immediately and loop until the specified condition has been met, with an appropriate pause between attempts.
Here's a sample interface for a Condition I use myself (as you can see, it doesn't need to be complex):
public interface Condition {
public boolean met();
}
void wait(long) is a part of the contract offered by Object and therefore it should not be changed. Imagine that someone stores your object and attempts to use it for wait/notify threading logic. So completely changing it's logic is just playing against the rules. So you will have to come up with different name.
On the other hand, it seems that having forUpdate take parameter indicating wait time will fit the bill. You could just have another version of forUpdate in addition to existing one.
What this requires is a way to disable an Object method. And main reason seems to be because it has a nice name that would fit the purposes of a proprietary API.
At first, this contradicts the entire idea of inheritance -- once you inherit from a class, all subclasses must expose the same non-private fields & method. You can always override a method, except when (1) it is marked as final and (2) it has an incompatible (non-covariant) return type, both of which are true with the void wait(long) method.
Furthermore, since every object is an Object in Java, everything must have a method void wait(long) and there should be no way to hide/delete/disable/forward/override it. Assuming it were possible to hide the void wait(long) method, how would you go about invoking it, should you wish to invoke it?
However, assuming you would never need to invoke void wait(long) for your particular classes, there is always the approach of source/byte-code weaving that AspectJ uses in order to make changes to the .class Java bytecode based on certain invocation rules. You could trap every call to wait(long) and declare an error/warning. See more here: http://www.eclipse.org/aspectj/doc/released/adk15notebook/annotations-decp.html
However, native method pointcuts are not possible even with AspectJ with byte-code weaving. Most likely, this is not possible even with source-code weaving -- but it might be worth a try.
Hacking around with core Java for the sake of DSL is simply not a good idea.
Why not make your DSL more expressive?
What does wait(int n) mean anyway? wait for N milliseconds, seconds, minutes?
A better signature would be:
wait(long duration, java.util.concurrent.TimeUnit){ ... }
which reads better, for example:
wait(30, TimeUnit.MILLISECONDS)