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.
Related
Suppose I have code that assigns a method to a Runnable, for example:
class C1{
Runnable r;
}
class C2{
void f(){}
}
var c1 = new C1();
var c2 = new C2();
c1.r = c2::f;
I want to write a unit test to assert that r is indeed assigned f, perhaps like this:
assertThat(c1.r).isEqualTo(c2::f); // Error: object is not a functional interface
Casting to Runnable does not help:
expected: ...$$Lambda$302/0x0000000800cd3518#1fe20588
but was : ...$$Lambda$301/0x0000000800c9fac0#77167fb7
In C# I can assign a method to an Action variable this assertion works. What's the equivalent in Java?
I am open to switching from Runnable to some other type, if that helps.
To give some more context: I'm trying to implement event-based decopuling like Arlo Belshee describes here: https://arlobelshee.com/decoupled-design/. Here's my C# implementation for comparison: https://jay.bazuzi.com/Decoupled-Design/
You're out of luck trying to compare lambdas in any sane way. The code may work in C# and other languages, but it's not worth trying to shoehorn it into Java.
I don't know the purpose of this exercise (as in is it just to test the viability of this in Java or if this is a pattern you regularly use), but generally translating from one language to another doesn't make sense unless there's an obvious compatibility. C# may look like Java (for some weird reason, hello J#), but there's a world of difference making many things completely distinct (e.g. async/await, only superficial similarity between LINQ and Java streams, methods not being truly first class objects in Java, and most likely many more as my C# knowledge is very limited).
IMHO the testing in the example was the weirdest part. It gives a low ROI to test microimplementation like that. I'm not sure if that is useful in GUI testing, but just as if you had a solution that involved metaprogramming, you couldn't just implement it in Java.
The thing is that you create a new method reference each time with ::.
Thus
var c1 = new C1();
var c2 = new C2();
Runnable r = c2::F;
c1.R = r;
System.out.println(c1.R == r);
will print true, because you assign and compare with the same runnable.
I need to unit test a certain method that works on an object of type X. The X object has few normal fields like String, int etc. but it also has a List of types Y. This Y type is also quite complex. And to make my problem even more difficult, let's say that the type Y has another list of type Z.
Ideally, I need to mock object X, but tell it to inject another mock of type Y inside, which should also inject another mock Z to itself (to Y). How should I do that?
And if I have so many few-levels mocks how should I avoid writing 20 specifications of what these mocks should actually return upon calling their methods?
Or is this a type of problem where I should use Builders and actually build a real object?
Thanks alot,
Bob.
Edit:
just an example usage code on top from my head:
public String produceImportantStringOfImportantData(ObjectX x) throws ParseException {
StringBuilder textResult = new StringBuilder();
List<ObjectY> listOfY = x.getListOfY();
if (listOfY.isValid()) {
for (ObjectY y : listOfY) {
for (ObjectZ z : y.getListOfZ()) {
textResult.append("<font color='green'>").append(z.getField2).append("</font>").append(": ").append(z.getSomething())
.append(" Label : ").append(z.getParentComponent.getField()))
.append(" some important labels: ").append(z.getField()))
.append(" some important labels ").append(y.getAnotherField))
.append(" different, important label: ").append(y.getField()))
.append("<br/>");
}
}
}
return textResult.toString();
}
Assuming you are using some mocking framework like Mockito, you could simply do:
X mockX = Mockito.mock(X.class);
Y mockX = Mockito.mock(Y.class);
Z mockX = Mockito.mock(Z.class);
Mockito.when(mockY.getZ()).thenReturn(mockZ);
Mockito.when(mockX.getY()).thenReturn(mockY);
If this gets too deep (you mention 20 specifications), it could be a sign that you are violating the Law of Demeter or the Single Responsibility Principle. In this case it means that your classes execute too much logic themselves rather than accepting some processors in their constructor which do the actual work.
If you would do this, you can test the processors separately and easily, and testing the entire process.
Please don't use mocks for this as there's absolutely no need to, but as you already seem to be aware, will lead to painful and fragile tests.
Or is this a type of problem where I should use Builders and actually build a real object?
You don't even need a Builder (although I do recommend them) - just use a real object. Using a real object will lead to a test that's must more resilient to refactoring, will test what your code is actually doing and not just what you think it is.
I'm having some difficulties about how to correctly design and implement two methods.
I have 2 methods, A and B. Method A does 2 things and method B does only 1 thing. One of the things that method A does is the same as what method B does, so it is very reasonable to call method B from within a method A.
Now the problem is that both methods need to send exactly one email to a user. When I invoke A, I want to receive 1 email and when I invoke B, I also want to get 1 email. This means that if I call method B inside A, I will now get 2 mails while doing 1 action (= invoking A). To make it even more tempting to simply include B in A, the set up procedure is truly the same for both methods and so instead of redoing the set up in the B, I could simply call method B with these set up data from A. But I have no setup data to provide when calling the B directly and so in this case I'd need to do the setup anyway.
What is the best approach to solve such a problem? Should I:
Add a parameter to method B in which I will say whether it should send the email or not and another parameters for the setup data
Keep the two methods separated, because method B is not doing exactly the same thing in the two contexts
... other suggestions?
PS. I'm not sure if stackoverflow is actually suitable for such a question, let me know if there's a better stackexchange platform for this.
Thanks for any ideas
I would suggest you split out the functionality a little further.
Currently you have two methods that might be described something like this:
void MethodA()
{
DoThing1();
DoThing2();
SendEmail();
}
void MethodB()
{
DoThing1();
SendEmail();
}
So one fairly simple answer is to extract the actual functional bits out of the two methods into methods of their own and leave behind a shell similar to the above. Each of the DoThingX methods can return whatever it is you need for building the email, etc.
Of course if the DoThingX methods are really small - a couple of lines or so, for instance - then it might not make sense to break them out this way.
I don't know if this is truly on-topic either. That said...
It seems to me that "sending email" is one of the things that is included in the method B work that method A needs done. As such, why not just implement it in method B? Then method A gets it for free when it calls method B.
If the exact contents of the email are different depending on whether method A was called or not, then sure…you can add a parameter to method B to customize the email in some way.
Finally, you're pretty vague on the details. It's not really clear just how much code you're saving by calling method B from method A. If it's significant, then I'm a strong proponent of code sharing like this. But if we're just talking a single statement, well...that seems less worth bothering with; maybe just putting that same single statement in each method is better.
Sorry for the vague answer. GIGO. :)
You could use the return of the methods for the content of our email:
private String funcA() {
// foo
return "Mail from funcA";
}
private String funcB() {
funcA(); // ignoring the return value here, we later return our on
// foo
return "Mail from funcB"; // our own return
}
Then you send the email outside of these functions (JUST EXAMPLE CODE):
private void mainFunc() {
String mail = condition ? funcA() : funcB();
sendMail(mail);
}
I have two ideas:
create C method that represents common functionality of A and B, and invoke C in A and B with different parameters
invoke B inside A, but extract mailing functionality alone to separate method C
To clarify the first idea:
methodA() {
firstAction();
secondAction(Parameter parameterFromA);
}
methodB() {
secondAction(Parameter parameterFromB);
}
I am trying to create a flyweight object in Java. I've worked with a similar concept in Objective-C (Singleton Classes in Objective-C // I believe they are the same thing).
I am trying to find a tutorial or an example or explanation online to learn how to create a flyweight object and use it, but I've searched on Google and I can't find anything descent. I went through 10 pages and they basically all plagiarize from one website which just explains the concept. I understand the concept - I need something to help me/teach me how to implement it in Java.
Anyone has any suggestions/tutorials?
Thanks!
The Wikipedia entry for the flyweight pattern has a concrete Java example.
EDIT to try and help the OP understand the pattern:
As noted in my comment below, The point of the flyweight pattern is that you're sharing a single instance of something rather than creating new, identical objects.
Using the Wiki example, the CoffeeFlavorFactory will only create a single instance of any given CoffeeFlavor (this is done the first time a Flavor is requested). Subsequent requests for the same flavor return a reference to the original, single instance.
public static void main(String[] args)
{
flavorFactory = new CoffeeFlavorFactory();
CoffeeFlavor a = flavorFactory.getCoffeeFlavor("espresso");
CoffeeFlavor b = flavorFactory.getCoffeeFlavor("espresso");
CoffeeFlavor c = flavorFactory.getCoffeeFlavor("espresso");
// This is comparing the reference value, not the contents of the objects
if (a == b && b == c)
System.out.println("I have three references to the same object!");
}
To follow up on the Wikipedia example that Brian cited...
Usually, if you want to cache some objects (such as CoffeeFlavors) and have them shared between a number of flyweights (the CoffeeOrders), then you would make them statically available. But this is not at all necessary. The important part is that the CoffeeOrders are being given the shared objects when they're constructed.
If the Orders are always only created by one singleton, like a "CoffeeOrderFactory," then the factory can keep a non-static cache of Flavors. However you accomplish it, your goal is to get all the Orders in the whole system to use the same exact set of Flavor objects. But at the end of the day, if you want to avoid creating many instances of CoffeeFlavor, then it usually needs to be created statically, just to make sure there's only one cache.
Get it?
I got this case. I think my solution was flyweight.
INPUT
A: C E
B: D C
C: E
A: B
It asked me to create a tree and sort its children by name. Something like this:
A: B C E
B: C D
C: E
It's an easy task actually. But please notice that the first 'A' and the second 'A' in the input must refer to same object. Hence I coded something like this
public Node add(String key){
Node node = nodes.get(key);
if (null == node){
node = new Node(key);
nodes.put(key, node);
}
return node;
}
This is the simplified version of the actual problem, but you should have the idea now.
I also found this example, which has good Java code example.
The "java.lang.Character" uses the flyweight pattern to cache all US-ASCII characters : see in class java.lang.Character$CharacterCache used by the Character.valueOf() method
I'm doing a bit of playing about to learn a framework I'm contributing to, and an interesting question came up. EDIT: I'm doing some basic filters in the Okapi Framework, as described in this guide, note that the filter must return different event types to be useful, and that resources must be used by reference (as the same resource may be used in other filters later). Here's the code I'm working with:
while (filter.hasNext()) {
Event event = filter.next();
if (event.isTextUnit()) {
TextUnit tu = (TextUnit)event.getResource();
if (tu.isTranslatable()) {
//do something with it
}
}
}
Note the cast of the resource to a TextUnit object on line 4. This works, I know it's a TextUnit because events that are isTextUnit() will always have a TextUnit resource. However, an alternative would be to add an asTextUnit() method to the IResource interface that returns the event as a TextUnit (as well as equivalent methods for each common resource type), so that the line would become:
TextUnit tu = event.getResource().asTextUnit;
Another approach might be providing a static casting method in TextUnit itself, along the lines of:
TextUnit tu = TextUnit.fromResource(event.getResource());
My question is: what are some arguments for doing it one way or the other? Are there performance differences?
The main advantage I can think of with asTextUnit() (or .fromResource) is that more appropriate exceptions could be thrown if someone tries to get a resource as the wrong type (i.e. with a message like "Cannot get this RawDocument type resource as a TextUnit - use asRawDocument()" or "The resource is not a TextUnit").
The main disadvantages I can think of with .asTextUnit() is that each resource type would then have to implement all the methods (most of which will just throw an exception), and if another major resource type is added there would be some refactoring to add the new method to every resource type (although there's no reason the .asSomething() methods would have to be defined for every possible type, the less common resources could just be cast, although this would lead to inconsistency of approach). This wouldn't be a problem with .fromResource() since it's just one method per type, and could be added or not per type depending on preference.
If the aim is to test an object's type and cast it, then I don't see any value in creating / using custom isXyz and asXyz methods. You just end up with a bunch of extra methods that make little difference to code readability.
Re: your point about appropriate exception messages, I would say that it is most likely not worth it. It is reasonable to assume that not having a TextUnit when a TextUnit is expected is symptom of a bug somewhere. IMO, it is not worthwhile trying to provide "user friendly" diagnostics for bugs. The person that the information is aimed at is a Java programmer, and for that person the default message and stacktrace for a regular ClassCastException (and the source code) provides all of the information required. (Translating it into pretty language adds no real value.)
On the flip-side, the performance differences between the two forms are not likely to be significant. But consider this:
if (x instanceof Y) {
((Y) x).someYMethod();
}
versus
if (x.isY()) {
x.asY().someYMethod();
}
boolean isY(X x) { return x instanceof Y; }
Y asY(X x) { return (Y) x; }
The optimizer might be able to do a better job of the first compared with the second.
It might not inline the method calls in the second case, especially if it is changed to use instanceof and throw a custom exception.
It is less likely to figure out that only one type test is really required in the second case. (It might not in the first case either ... but it is more likely to.)
But either way, the performance difference is going to be small.
Summary, the fancy methods are not really worth the effort, though they don't do any real harm.
Now if the isXyz or asXyz methods were testing the state of the object (not just the object's Java type), or if the asXyz was returning a wrapper, then the answers would be different ...
You could also just go
if (event instanceof TextUnit) {
// ...
}
and save yourself the trouble.
To answer your question regarding whether to go asTextUnit() vs. TextUnit.fromResource, the performance difference would depend upon how you actually implement these methods.
In the case of the static converter you would have a to create and return a new object of type TextUnit. However, in the case of the member function you could simply return this casted or you could create an return a new object - depends upon your use case.
Either ways, seems like instanceof is probably the cleanest way here.
What if your filter were extended - or wrapped - to return only text unit events? In fact, what if it returned only the resources of text unit events? Then your loop would be much simpler. I would think the clean way to do this would be a second filter, which simply returned just the text unit events, followed by, let's say, an Extractor, which returned the properly cast resource.
If you have a common base class, you can have a single asXMethod there for every derived class, and needn't refactor all derived classes:
abstract class Base {
A asA () { throw new InstantiationException ("not an A"); }
B asB () { throw new InstantiationException ("not an B"); }
C asC () { throw new InstantiationException ("not an C"); }
// much more ...
}
class A extends Base {
A asA () { /* hard work */ return new A (); }
// no asB, asC requiered
}
class B extends Base {
B asB () { /* hard work */ return new B (); }
// no asA, asC required
}
// and so on.
looks pretty clever. For a new Class N, just add a new Method to Base, and all derived classes get it. Just N needs to implement asN.
But it smells.
Why should a B have a method asA if it will always fail? That's not a good design. Exceptions in the generator are cheap, if they aren't triggered. Only thrown exceptions might be costly.
Yes, there are differences. Creating new immutable elements is better then casting. Pass all serializable data (non transient or computable data) to a Builder and build appropriate class.