I have an adapter from I1 to ILogger implemented like this:
class BAdapter() implements I1
{
void logA() { // nothing }
void logB() { new BLogger().log() }
void logC() { // nothing }
}
I would like to write JUnit test, that verify the functionality, but I found it a bit problematic, since I cannot inject my Mock object instead of BLogger, or verify return value. I found several possible solution, but I am not sure, which is the best.
Case One:
Add void setLogger(Logger l) to the BAdapter class.
class BAdapter() implements I1
{
private Logger logger = new BLogger();
public void logB() { logger.log() }
public void setLogger(Logger l) { logger = l }
.. //rest of methods
}
Cons: Why to add setter which is never used in "real", non-testing code?
Case Two:
Add protected factory method and sublcass BAdapter in test package.
class BAdapter() implements I1
{
public void logB() { createLogger().log() }
protected Logger createLogger() { retrun new BLogger() }
.. //rest of methods
}
class BAdapterForTesting extends BAdapter()
{
protected Logger createLogger() { retrun new MockBLogger() }
}
Cons: I am not sure, if this is clean and elegant solution, but I don't see much cons here.
Case Three:
Use Abstract Factory pattern.
class BAdapter() implements I1
{
public void logB() { AbstractFactory.getFactory().getBLogger().log() }
.. //rest of methods
}
And somewhere in tests:
AbstractFactory.setFactory(new MockLoggersFactory())
Cons: This is too complex, isn't it?
Case Four:
Return Boolean, for example, when logging was performed. E.g.
class BAdapter() implements I1
{
Boolean logA() { return false; }
Boolean logB() { return new BLogger().log() }
Boolean logC() { return false; }
}
Cons: This is kind of wourkaround. Why to return some value, when nobody needs it in "real", non-testing code?
Better Solution?
Is there anything better?
From your code it's hard to tell exactly what the class under test is trying to achieve but
I'd go with Case One with the caveat that I'd use injection in the 'real' code too.
One of the benefits of injection is it makes the class, in this case your adapter, more re-usable. Forcing the logB method to always delegate to an instance of BLogger sets that behaviour in stone at compile time. If I want the adapter to delegate to another type of Logger I can't use it and it is therefore slightly less re-usable.
IMVHO creating code especially to be used by tests and nowhere else is not a good idea as it may expose functionality that is not supposed to be used, yet some may think using it is cool and be badly surprised.
This leaves us with case 3 which is a generally very good approach, yet if it is only to be used during testing its still a bit of overkill.
I'd suggest using some additional mocking framework like PowerMock which can change private fields in classes in convenient way:
class BAdapter() implements I1
{
private Logger logger = new BLogger();
public void logB() { logger.log() }
.. //rest of methods
}
and then during testing swap the field to some mock:
Whitebox.setInternalState(loggerInstance, "logger", new MockLogger());
more info:
http://code.google.com/p/powermock/wiki/BypassEncapsulation
Mocking frameworks are great asset during testing so knowing them helps a lot.
Related
I do have a service which needs to handle two types of meal.
#Service
class MealService {
private final List<MealStrategy> strategies;
MealService(…) {
this.strategies = strategies;
}
void handle() {
var foo = …;
var bar = …;
strategies.forEach(s -> s.remove(foo, bar));
}
}
There are two strategies, ‘BurgerStrategy’ and ‘PastaStrategy’. Both implements Strategy interface with one method called remove which takes two parameters.
BurgerStrategy class retrieves meals of enum type burger from the database and iterate over them and perform some operations. Similar stuff does the PastaStrategy.
The question is, does it make sense to call it Strategy and implement it this way or not?
Also, how to handle duplications of the code in those two services, let’s say both share the same private methods. Does it make sense to create a Helper class or something?
does it make sense to call it Strategy and implement it this way or not
I think these classes ‘BurgerStrategy’ and ‘PastaStrategy’ have common behaviour. Strategy pattern is used when you want to inject one strategy and use it. However, you are iterating through all behaviors. You did not set behaviour by getting one strategy and stick with it. So, in my honour opinion, I think it is better to avoid Strategy word here.
So strategy pattern would look like this. I am sorry, I am not Java guy. Let me show via C#. But I've provided comments of how code could look in Java.
This is our abstraction of strategy:
public interface ISoundBehaviour
{
void Make();
}
and its concrete implementation:
public class DogSound : ISoundBehaviour // implements in Java
{
public void Make()
{
Console.WriteLine("Woof");
}
}
public class CatSound : ISoundBehaviour
{
public void Make()
{
Console.WriteLine("Meow");
}
}
And then we stick with one behaviour that can also be replaced:
public class Dog
{
ISoundBehaviour _soundBehaviour;
public Dog(ISoundBehaviour soundBehaviour)
{
_soundBehaviour = soundBehaviour;
}
public void Bark()
{
_soundBehaviour.Make();
}
public void SetAnotherSound(ISoundBehaviour anotherSoundBehaviour)
{
_soundBehaviour = anotherSoundBehaviour;
}
}
how to handle duplications of the code in those two services, let’s say both share the same private methods.
You can create one base, abstract class. So basic idea is to put common logic into some base common class. Then we should create abstract method in abstract class. Why? By doing this, subclasses will have particular logic for concrete case. Let me show an example.
An abstract class which has common behaviour:
public abstract class BaseMeal
{
// I am not Java guy, but if I am not mistaken, in Java,
// if you do not want method to be overriden, you shoud use `final` keyword
public void CommonBehaviourHere()
{
// put here code that can be shared among subclasses to avoid code duplication
}
public abstract void UnCommonBehaviourShouldBeImplementedBySubclass();
}
And its concrete implementations:
public class BurgerSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
public class PastaSubclass : BaseMeal // extends in Java
{
public override void UnCommonBehaviourShouldBeImplementedBySubclass()
{
throw new NotImplementedException();
}
}
public boolean sendRequest(final Object... params) {
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Why not implement a new method to call sendRequest rather than overwrite?
public boolean Send(final Object... params){
if (!super.sendRequest(params)) {
return false;
}
...
// Some Log code or tracing code here
...
}
Do you want your class with the override to be able to be used in the same way as members of the original class? i.e.:
...
class MyClass extends TheirClass {
#Override
void doIt() {
super.doIt();
// also do my stuff
}
}
...
// the doSomething function is part of the library where TheirClass lives.
// I can pass instances of MyClass to it, and doIt will be called, because MyClass IS-A TheirClass
theirFunction.doSomething(new MyClass(...));
...
But perhaps you just want to use the functionality of doIt, but don't need to use and code which expects a TheirClass.
In that case it is probably better to use composition rather than inheritance:
class MyClass {
private final TheirClass theirClass;
public MyClass(TheirClass theirClass) {
this.theirClass = theirClass;
}
public void doMyStuff() {
theirClass.doIt();
// and do some other things
}
}
This is better than inheritance with a new method name, because then you would have two methods on the class which do about the same thing (except the original doIt doesn't do your stuff), and it may not be clear which should be called.
Even inheritance where you override the method may have problems. We don't know what code in TheirClass calls doIt, so perhaps the code we've added will be called when we don't expect it to be.
Overall, composition should be preferred to inheritance whenever possible.
I have a class similar to this:
public class QueueingCommandRunner {
private Status status;
private Map<Class<CommandHandler>, CommandHandler> queuedCommands;
private RunnerClass runnerClass;
private ExternalCommandRunnerRegistry externalCommandRunnerRegistry;
private ExternalCommandRunner externalCommandRunner;
public QueueingCommandRunner(ExternalCommandRunnerRegistry externalCommandRunnerRegistry,
RunnerClass runnerClass) {
this.externalCommandRunnerRegistry = externalCommandRunnerRegistry;
this.runnerClass = runnerClass;
this.queuedCommands = new LinkedHashMap<>();
this.status = Status.DOWN;
}
public void init() {
doSomeStuff();
externalCommandRunner = externalCommandRunnerRegistry.get(runnerClass);
externalCommandRunner.runListeningCommand(ListenableStatusCommand.class,
new ListenableStatusHandler(this::changeStatus));
}
public <T extends CommandHandler> void runCommand(Class<T> command, T commandHandler) {
if (status == UP) {
externalCommandRunner.run(command, commandHandler);
} else {
queuedCommands.put(command, commandHandler);
}
}
private void changeStatus(Status status) {
this.status = status;
if (status == UP) {
Iterator<Entry<Class<CommandHandler>, CommandHandler>> commandsIterator =
queuedCommands.iterator();
while (commandsIterator.hasNext()) {
<Entry<Class<CommandHandler>, CommandHandler>> queuedCommand = commandsIterator.next();
externalCommandRunner.run(queuedCommand.getKey(), queuedCommand.getValue());
commandsIterator.remove();
}
}
}
}
I omit stuff like synchronization. My question is, how to test queuing which is inside without using things like invocation of private methods via reflection? In particular I would like to know how to test changeStatus method since it is not directly run from any public method in this class. Is this class bad by design (from unit testing point of view)?
I am using JMockit for testing...
As it was mentioned in the comment - you test
desired public observable behavior
So, if you want to test private methods you need to make them public. I suggest to make it as interface:
public interface SomeInterface {
changeStatus(Status status);
}
Then inject implementation to your class:
public final class A {
private final SomeInterface someInterface;
public A(SomeInterface someInterface) {
this.someInterface = someInterface;
}
}
Then you can easily test SomeInterface implementation and mock if you need it in your class A.
So, I cannot give you the whole refactoring process for your particular case. But you can follow this guideline and you can encapsulate all private methods with interfaces that are tested easily. As I can see, you are using internal details of your class in private methods - these details should be encapsulated in interface implementation constructor (via another interfaces) and you will end up with small nice cohesive testable classes. Look through Command Pattern as it seems suitable for your case and try to follow SOLID which will also lead to testable code.
I see several problems with your design:
init() method. Which leads to temporal coupling as your class is not ready to use after construction;
your runCommand method is doing two things based on status. It's either run command or put it to map (which is hidden side-effect);
your changeStatus is also running comands.
You need to decouple those thins (running command, holding them and tracing status). Maybe encapsulate status of the command inside command itself. So the command will know how to work in its own way.
In short, I'd like to be able to group class instances by a superclass which does not implement a certain interface. But from the set of instances I'd like to call methods from the interface on those instances that implement that interface.
Some example code which might explain it.
class Building{
String c = "white";
Building(){
}
void printColor(){
println("The building is " + c);
}
void paint( String c ){
this.c = c;
}
void printBuildQuality(){
println("The build quality is average");
}
}
class SturdyFactoryBuilding extends Building implements Factory{
SturdyFactoryBuilding(){
super();
}
void printBuildQuality(){
println("The build quality is sturdy");
}
void printFactoryOutput(){
println("This factory makes stuff");
}
}
class ShakyFactoryBuilding extends Building implements Factory{
ShakyFactoryBuilding(){
super();
}
void printBuildQuality(){
println("The build quality is shaky");
}
void printFactoryOutput(){
println("This factory makes slightly different stuff");
}
}
public interface Factory{
public void printFactoryOutput();
}
Building building = new SturdyFactoryBuilding();
building.printBuildQuality();
building.printColor();
building.paint("bright red");
building.printColor();
building.printFactoryOutput();
Is there a way I can achieve this, perhaps by having an 'isFactory' flag in the superclass.
Thanks.
I think you'll have to make a trade-off: Either you accept some anti-pattern or you open up you Building "interface" to act as an Adapter:
class Building implements Factory{
// the other building stuff
#Override
public void printFactoryOutput(){ /* NO OP */ }
}
Then you can call printFactoryOutput on all Buildings having no effect up to this point.
Since your Factory-implementations extend Building they automatically inherit the NOOP-Implementation. But since you override it:
class ShakyFactoryBuilding extends Building implements Factory{
ShakyFactoryBuilding(){
super();
}
#Override
public void printBuildQuality(){
println("The build quality is shaky");
}
#Override
public void printFactoryOutput(){
println("This factory makes slightly different stuff");
}
}
... you have the desired result.
Drawback is of course that all Buildings do have the printFactoryOutput visible. But that's the trade-off I was talking about. If this is not acceptable, you'll have to completely reconsider your design.
To make it clear that a Building that is not a Factory shall not be called that Method on, you could throw an UnsupportedOperationException in Building, but that would force try/catch blocks everywhere in your code. You could as well return a boolean: default=false and returning true if in fact a factory ... There are plenty possibilities.
You could also change your design to use composition over inheritance.
I think you're getting the message that this is a bad idea. It violates generally accepted object oriented design principles. That said, there are several ways to go about it, some less odious than others.
Just cast it
The simplest thing to do is something like this:
if (building instanceof Factory)
((Factory)building).printFactoryOutput();
You're checking to see whether it's a Factory, then invoking the Factory-specific method after casting. It's a straightforward (and therefore easily understood) way of implementing a bad design.
Make Building aware of Factory
This has issues in that there is currently no necessary relationship between Building and Factory, but such a relationship might help you along.
class Building {
// ...
Factory adaptToFactory() {
return null;
}
}
class SturdyFactoryBuilding ... {
// ...
#Override
Factory adaptToFactory() {
return this;
}
}
Similarly for ShakyFactoryBuilding.
Then you could write
Factory f = building.adaptToFactory();
if (f != null)
f.printFactoryOutput();
More general adapter
If you're doing a lot of this kind of thing, you could make it into a pattern that you apply wherever needed. (Eclipse, for example, uses adapters all over the place.)
interface Adaptable {
<T> T adapt(Class<T> clazz);
}
class Building implements Adaptable {
// ...
#Override
<T> T adapt(Class<T> clazz) {
if (clazz.isInstance(this)) {
return clazz.cast(this);
}
return null;
}
}
Then you'd write
Factory f = building.adapt(Factory.class);
if (f != null)
f.printFactoryOutput();
There are still more places to go with this, but this is far enough for this question, I think.
Imagine you have an application and you want to make unit tests and functionnal tests over it (not quite hard to imagine). You might have an abstract class, let's call it AbstractTestClass, from which all your unit tests extends.
AbstractTestClass would look something like this (using JUnit 4) :
class AbstractTestClass {
boolean setupDone = false;
#Before
public void before() {
if(!setupDone) {
// insert data in db
setupDone = true;
}
}
}
Here is what I'm struggling with. I'm having another abstract class which test the web interfaces :
class AbstractWebTestClass extends WebTestCase {
boolean setupDone = false;
#Before
public void before() {
if(!setupDone) {
// here, make a call to AbstractTestClass.before()
// init the interfaces
setupDone = true;
}
// do some more thing
}
}
It's pretty much the same class, except that it extends WebTestCase. This design could give me the possibility to have the same data while unit testing than when testing the interface.
Usually, when dealing with such issue, you should favor composition over inheritance or use a strategy pattern.
Unfortunately, I don't quite like the idea to favor composition over inheritance in this particular scenario and I don't see how I could use a strategy pattern, there is probably a design flaw and I can't quite see the solution.
How could I design this architecture in order to achieve my goal.
I would implement this in the following way:
class Example {
class LazyInitStrategy implements Runnable {
private final Runnable operation;
private boolean done = false;
LazyInitStrategy(Runnable operation) {
this.operation = operation;
}
#Override
public void run() {
if (!done) {
operation.run();
done = true;
}
}
}
private final class AbstractInit implements Runnable {
public void run() {
// insert data in db
}
}
private final class AbstractWebInit implements Runnable {
public void run() {
// here, make a call to AbstractTestClass.before() init the interfaces
}
}
class AbstractTestClass {
final LazyInitStrategy setup = new LazyInitStrategy(new AbstractInit());
#Before
public void before() {
setup.run();
// do some more thing
}
}
class AbstractWebTestClass extends WebTestCase {
final LazyInitStrategy setupInfo = new LazyInitStrategy(new AbstractWebInit());
#Before
public void before() {
setupInfo.run();
// do some more thing
}
}
}
Sure this is very simplistic solution but it should eliminate if/else logic duplication for checking if setup was done. Using Runnable is optional, I did this just for demo purposes, in read world you probably will use another interface.
The important thing to accomplish is not to duplicate code. In this situation I would create a
MyScenarioTestUtil
class that has a bunch of static methods on it that sets up the data as you need to. You would invoke the utility methods from the setup. That way you keep all the code in one place.
Its really just a semantics difference from using composition...
I think that the design is wrong in general. You shouldn't use inheritance in unit tests at all. Tests should be isolated and really plain. Very often, like in your case, it's necessary to prepare some supplementary objects, that will help test methods to do their job. In such a case you should define builders of such objects, and place them somewhere outside of test cases.
For example:
public void testMethodThatNeedsSomePreparedObjects() {
Foo foo = new FooBuilder()
.withFile("some-text.txt")
.withNumber(123)
.build();
// now we are testing class Bar, using object of class Foo
Bar bar = new Bar(foo);
}
Thus, you need FooBuilder to be defined somewhere else, and this class will do all the work you're now trying to do using stategy pattern or inheritance. Both approached are wrong, when dealing with unit tests.