I have following structure of my code:
class A has dependency on class B, which fetches instance of another class C, which in turn contains a List l.
I need to unit test a method in A which gets hold of List l, and updates it.
I am not sure how to go about it? Should I mock a List and put it in mock of C, and then validate its updates. I am not sure if that's even possible.
You want to test a method M in class A. Method M does tricky things with a class B in order to obtain a List<E> I which is modified.
Depending on your class design, you might be able to proceed as follows:
Create a mock of class B so that so that the method used to “get hold of I” returns some interesting, real list I
Inject this mock into your class-under-test A
Invoke your method-under-test M
Assert that the changes to your list are as intended.
If creating the elements of class E in the list is complicated, you could mock those elements, but there is no need to mock the list itself.
Related
Say I have open class C(val c:C) and I want to subclass it as class D():C(this)
This is invalid according to the compiler because 'this' is not defined in this context
Is there a way to get this to do what I want? Specifically, I'd like for D to have a constructor that can be called without any arguments and will pass the D object being constructed to C's constructor. In my case, it's fine that this object may not be fully constructed yet.
I'm open to any solutions that don't involve changing C, reflection included.
There's no straightforward solution, because it does not seem to be a good idea.
The constructor of the super class gets executed before the constructor of the class itself does (more details here). Thus passing this instance that has not been initialized at all to the super constructor in place of a valid instance may break some of the logic of the super constructor (e.g. it may expect the c's properties to have some meaningful values, but they don't).
If you need this so bad, you can try to create an instance of D first with some fake/default C, then create another D with the first one:
class D(c: C) : C(c)
fun createD(defaultC: C): D {
val firstD = D(defaultC)
return D(firstD)
}
Though this definitely does not cover all possible use cases.
The following code was taken from this post: How to create Scala swing wrapper classes with SuperMixin?
import scala.swing._
import javax.swing.JPopupMenu
class PopupMenu extends Component with SequentialContainer.Wrapper {
override lazy val peer: JPopupMenu = new JPopupMenu with SuperMixin
def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y)
}
I've been trying to make custom wrappers so need to understand this, which is simple enough but since
I'm only starting to get acquainted with Scala so I'm a little unsure about traits. So what I've been hearing is that traits is like multiple inheritance and you can mix and match them?
I've drawn a diagram representing where PopupMenu sits within the whole inheritance structure. Just to clarify a few things:
1) It seems to override lazy val peer:JComponent from Component and also gets the contents property from SequentialContainer.Wrapper? (purple text) Is that right?
2) Sequential.Wrapper also has a abstract def peer: JComponent.. but this isn't the one being overriden, so it isn't used at all here?
3) What's confusing is that Component and Sequential.Wrapper have some identical properties: both of them have def publish and def subscribe (red text).. but the one that the popupMenu will use is subscribe/publish from the Component class?
4) why can't we write PopupMenu extends SequentialContainer.Wrapper with Component instead?
Hopefully that isn't too many questions at once. Help would be much appreciated, I'm a beginner to Scala..
I'll answer using the numbers of your questions:
Correct
Correct. The top trait is UIElement which defines an abstract member def peer: java.awt.Component. Then you have Container which merely adds abstract member def contents: Seq[Component] to be able to read the child components. Container.Wrapper is a concrete implementation of Container which assumes (abstractly) the Java peer is a javax.swing.JComponent. Note that in Java's own hierarchy, javax.swing.JComponent is a sub-type of java.awt.Component, so there is no conflict. Sub-types can refine the types of their members ("covariance"). SequentialContainer refines Container by saying that contents is a mutable buffer (instead of the read-only sequence). Consequently, its implementation SequentialContainer.Wrapper mixes in Container.Wrapper but replaces the contents by a standard Scala buffer. At no point has a concrete peer been given, yet. For convenience, Component does implement that member, but then as you have seen, the final class PopupMenu overrides the peer. Because of the way the type system works, all the participating traits can access peer, but only PopupMenu "knows" that the type has been refined to be javax.swing.JPopupMenu. For example SequentialContainer.Wrapper only knows there is a javax.swing.JComponent, and so it can use this part of the API of the peer.
The Publisher trait is introduced by UIElement, so you will find it in all types deriving from UIElement. There is nothing wrong with having the same trait appear multiple times in the hierarchy. In the final class, there is only one instance of Publisher, there do not exist multiple "versions" of it. Even if Publisher had not been defined at the root, but independently in for example Component and SequentialContainer.Wrapper, you would only get one instance in the final class.
This is an easy one. In Scala you can only extend one class, but mix in any number of traits. Component is a class while all other things else are traits. It's class A extends <trait-or-class> with <trait> with <trait> ....
To sum up, all GUI elements inherit from trait UIElement which is backed up by a java.awt.Component. Elements which have child elements use trait Container, and all the normal panel type elements which allow you to add and remove elements in a specific order use SequentialContainer. (Not all panels have a sequential order, for example BorderPanel does not). These are abstract interfaces, to get all the necessary implementations, you have the .Wrapper types. Finally to get a useable class, you have Component which extends UIElement and requires that the peer is javax.swing.JComponent, so it can implement all the standard functionality.
When you implement a new wrapper, you usually use Component and refine the peer type so that you can access the specific functionality of that peer (e.g. the show method of JPopupMenu).
I see Java has only one metaclass (the Class class), but other languages, say Smalltalk, have one metaclass for each Class.
Why is that? What's the need for metaclasses? What difference does it make to have them one way or another?
The fundamental need for at least one metaclass is that if you want objects that represent classes (or want classes to be objects), then those objects must have a type.
Wikipedia says:
In early Smalltalks, there was only one metaclass called Class. This
implied that the methods all classes have were the same, in particular
the method to create new objects, i.e., new. To allow classes to have
their own methods and their own instance variables (called class
instance variables and should not be confused with class variables),
Smalltalk-80 introduced for each class C their own metaclass C class.
So the question is, do you want every class object to have the same type (and hence the same members), or do you want class objects to differ in ways that require them to have different types, so that there are type-checked operations which can be performed on the object that represents class A but not on the object that represents class B? Java and early Smalltalks answered that question differently from later Smalltalks.
So for example java.lang.Class.newInstance() takes no constructor arguments, whereas you can imagine that it might be nice to be able to call clz.newInstance(1) where clz is the class object for a class that has a constructor with takes an int. In Java you can still look through the constructors of the class yourself to find a match for the arguments you want to pass, but the type of the class object doesn't tell you whether you will find one.
Also note that Smalltalk stops at one level. The type of C is C class, but the type of C class is Metaclass. There's no infinite recursion of types C class class etc, because although different class objects in Smalltalk accept different messages, there's no demand for different metaclass objects to accept different messages.
Is this a good idea? Instead of create a class with two method (insert and update) and two validation methods (validateInsert and validateUpdate), create three classes: one called ProductDB, another ProductInsert (with methods Insert and Validate) and another ProductUpdate (with same methods of ProductInsert).
Is this more readable, flexible and testable?
PaulG's answer leans more towards the traditional domain object pattern, which I'm not in favor of. Personally, my preference is to have a separate class for each process (like your ProductInsert and ProductUpdate). This is akin to what one sees in the simple bank example where Deposit is a instance of a class as opposed to a method on a BankAccount class. When you start thinking about business processes that have more stuff, like rules and actions to be taken and auditing/persistence of the action itself (say a ProductInsert table to track insertions), the more you realize the business process should be a first class citizen in its own right.
This sounds like a language-independent question. I would just create the one class and call it Product, and have the appropriate methods within the class. Think about what a mess it would be when actually instantiating your separate objects (unless you have static methods).
Also having a concrete Product class will allow you to store object specific information.
Ex:
Product myProduct = new Product()
myProduct.name = "cinnamon toast crunch"
myProduct.price = 3.99
In my opinion have separate classes would make your code a lot less readable and testable.
I'm writing a program to do a search and export the output.
I have three primary objects:
Request
SearchResults
ExportOutput
Each of these objects links to its precursor.
Ie: ExportOutput -> SearchResults -> Request
Is this ok? Should they somehow be more loosely coupled?
Clarification:
Processes later on do use properties and methods on the precursor objects.
Ie:
SendEmail(output.SearchResults.Request.UserEmail, BODY, SUBJECT);
This has a smell even to me. The only way I can think to fix it is have hiding properties in each one, that way I'm only accessing one level
MailAddress UserEmail
{
get { return SearchResults.UserEmail; }
}
which would yeild
SendEmail(output.UserEmail, BODY, SUBJECT);
But again, that's just hiding the problem.
I could copy everything out of the precursor objects into their successors, but that would make ExportOutput really ugly. Is their a better way to factor these objects.
Note: SearchResults implements IDisposable because it links to unmanaged resources (temp files), so I really don't want to just duplicate that in ExportOutput.
If A uses B directly, you cannot:
Reuse A without also reusing B
Test A in isolation from B
Change B without risking breaking A
If instead you designed/programmed to interfaces, you could:
Reuse A without also reusing B - you just need to provide something that implements the same interface as B
Test A in isolation from B - you just need to substitute a Mock Object.
Change B without risking breaking A - because A depends on an interface - not on B
So, at a minimum, I recommend extracting interfaces. Also, this might be a good read for you: the Dependency Inversion Principle (PDF file).
Without knowing your specifics, I would think that results in whatever form would simply be returned from a Request's method (might be more than one such method from a configured Request, like find_first_instance vs. find_all_instances). Then, an Exporter's output method(s) would take results as input. So, I am not envisioning the need to link the objects at all.