Stub only one private static method in a class - java

I have a class that I am unit testing. It looks like following:
public class classToUT {
public static Event getEvent(String id) {
return getEvent(id, null);
}
private static Event getEvent(String id, String name) {
//do something
logEvent(id, name);
return event;
}
private static void logEvent(String id, string name) {
// do some logging
}
}
There are external util methods being called in logEvent that I want to avoid. Basically, I want only logEvent to be stubbed out but all other methods to be called in my unit test. How do I stub out this one method only?
public void UTClass {
#Test
public void testGetEvent() {
assertNotNull(event, classToUt.getEvent(1)); //should not call logEvent
//but call real method for getEvent(1) and getEvent(1, null)
}
}

Try the following ...
#RunWith(PowerMockRunner.class)
#PrepareForTest(PowerTest.ClassToUT.class)
public class PowerTest {
public static class ClassToUT {
public static String getEvent(String id) {
return getEvent(id, null);
}
private static String getEvent(String id, String name) {
// do something
logEvent(id, name);
return "s";
}
private static void logEvent(String id, String name) {
throw new RuntimeException();
}
}
#Test
public void testGetEvent() throws Exception {
PowerMockito.spy(ClassToUT.class);
PowerMockito.doNothing().when(ClassToUT.class, "logEvent", any(), any());
Assert.assertEquals("s", ClassToUT.getEvent("xyz"));
}
}

Related

Dependency Injection: How to get access to the corresponding ProductView that executes the Command?

I want to execute commands for each product view. Consider 10 products views, and each of them can execute the PrintProductViewCommand. This command, takes in constructor a ProductView and prints its name. Since it is #Injectable, the container will create a new ProductView each time the command is created. The following example shows what I want to do:
public class InjectionTest {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(ProductView.class);
bind(CommandExecutor.class);
bind(PrintProductViewNameCommand.class);
install(new FactoryModuleBuilder().implement(ProductView.class, ProductView.class)
.build(ProductViewFactory.class));
}
});
List<ProductView> productViews = new ArrayList<>();
ProductViewFactory factory = injector.getInstance(ProductViewFactory.class);
for (int i = 0; i < 10; i++) {
productViews.add(factory.create("Name: " + String.valueOf(i)));
}
System.out.println("Done creating");
//Now sometime in future, each product view calls print method
productViews.forEach(ProductView::print);
}
private static interface ProductViewFactory {
ProductView create(String name);
}
private static class ProductView {
private String name; //simulate a property
private CommandExecutor executor;
public ProductView() {
//Guice throws exception when this is missing
//Probably because it is being asked in PrintProductViewCommand
}
#AssistedInject
public ProductView(#Assisted String name, CommandExecutor executor) {
this.name = name;
this.executor = executor;
}
public String getName() {
return name;
}
//assume some time product view it self calls this method
public void print() {
executor.execute(PrintProductViewNameCommand.class);
}
}
#Singleton
private static class CommandExecutor {
#Inject
private Injector injector;
public void execute(Class<? extends Command> cmdType) {
injector.getInstance(cmdType).execute();
}
}
private static class PrintProductViewNameCommand implements Command {
private ProductView view;
#Inject
public PrintProductViewNameCommand(ProductView view) {
this.view = view;
}
#Override
public void execute() {
//Want to print "Name: something" here
System.out.println(view.getName());
}
}
private static interface Command {
void execute();
}
}
This problem is solved if I add a parameter to Command interface, and make it Command<T>. Then CommandExecutor will have this method:
public <T> void execute(Class<? extends Command<T>> cmdType, T parameter) {
injector.getInstance(cmdType).execute(parameter);
}
So, my PrintProductViewNameCommand is now class PrintProductViewNameCommand implements Command<ProductView>, and in product view :
public void print() {
executor.execute(PrintProductViewNameCommand.class,this);
}
However, the Command Pattern has no parameter in execute(). I have also seen somewhere that adding a parameter is an anti-pattern.
Of course, the command is simple. Assume that the command has other dependencies too, like Services etc.
Is there a way I can achieve it? Perhaps I am doing something wrong, probably with the whole DI situation.
When not using dependency injection, I would do something like this:
ProductView view = new ProductView();
Command command = new PrintProductViewNameCommand(view);
view.setPrintCommand(command);
But how to it while using DI?
So this works, although I'm not sure if it's 100% what you want to do.
public class InjectionTest {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(CommandExecutor.class);
bind(ProductView.class);
install(new FactoryModuleBuilder()
.implement(ProductView.class, ProductView.class)
.build(ProductViewFactory.class));
install(new FactoryModuleBuilder()
.implement(PrintProductViewNameCommand.class, PrintProductViewNameCommand.class)
.build(PrintProductViewNameCommand.Factory.class));
}
});
ProductViewFactory factory = injector.getInstance(ProductViewFactory.class);
List<ProductView> productViews = new ArrayList<>();
for (int i = 0; i < 10; i++) {
productViews.add(factory.create("Name: " + i));
}
System.out.println("Done creating");
//Now sometime in future, each product view calls print method
productViews.forEach(ProductView::print);
}
private interface ProductViewFactory {
ProductView create(String name);
}
private static class ProductView {
private String name;
private CommandExecutor executor;
private PrintProductViewNameCommand printProductViewNameCommand;
#AssistedInject
public ProductView(#Assisted String name, PrintProductViewNameCommand.Factory printProductViewNameCommandFactory, CommandExecutor executor) {
this.name = name;
this.executor = executor;
this.printProductViewNameCommand = printProductViewNameCommandFactory.create(this);
}
public ProductView() {}
public String getName() {
return name;
}
//assume some time product view it self calls this method
public void print() {
executor.execute(printProductViewNameCommand);
}
}
#Singleton
private static class CommandExecutor {
public void execute(Command command) {
command.execute();
}
}
private static class PrintProductViewNameCommand implements Command {
private final ProductView view;
#AssistedInject
public PrintProductViewNameCommand(#Assisted ProductView view) {
this.view = view;
}
static interface Factory {
PrintProductViewNameCommand create(ProductView productView);
}
#Override
public void execute() {
//Want to print "Name: something" here
System.out.println(view.getName());
}
}
private static interface Command {
void execute();
}
}
Basically what you're running into is a cyclic dependency problem (https://github.com/google/guice/wiki/CyclicDependencies#use-factory-methods-to-tie-two-objects-together) that's also exasperated by a bit by the fact that you have an additional AssistedInject in the ProductView.
By the way I'm using Guice 3 in this example.

How to change the value of private variable in java

I started to programm in Java since Yesterday, and I have the biggest question of my entire programmer life(since Yesterday).
For example, let's say I have a code like this:
public class itsAClass {
static private String A;
public static void main() {
A = "This should be changed";
}
public String something() {
return A;
}
}
I wanted to use the method something() in another Class to get the String Sentence of A, but I got only null.
How can I change the value of A, so that the another Class can get the Value "This should be changed"?
If you just want to bring this code to work you just can make something() static as well.
But this will be not the right way to approach this problem.
If you want to hold code in the main class you could do something like this:
public class AClass {
private String a;
public static void main() {
AClass myC = new AClass();
myC.setA("This should be changed");
// than use myC for your further access
}
public String something() {
return a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
}
If you want to access it by a external class without direct reference you can checkout the singleton pattern.
public class AClass {
private final static AClass INSTANCE = new AClass();
private String a;
public static void main() {
getSingleton().setA("This should be changed");
}
public String something() {
return a;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public static AClass getSingleton() {
return INSTANCE;
}
}
This way you can access it via AClass.getSingleton() from any location of your code.
You have to call your main() function.
In another class:
itsAClass aClassObj = new itsAClass();
aClassObj.main();
// or rather itsAClass.main() as it is a static function
// now A's value changed
System.out.println(aClassObj.something());
the way to set the value of private variable is by setter and getter methods in class.
example below
public class Test {
private String name;
private String idNum;
private int age;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getIdNum() {
return idNum;
}
public void setAge( int newAge) {
age = newAge;
}
public void setName(String newName) {
name = newName;
}
public void setIdNum( String newId) {
idNum = newId;
}
}
you can call method main() in method something().
public class itsAClass{
static private String A;
public static void main() {
A = "This should be changed";
}
public String something() {
main();
return A;
}
public static void main(String[] args){
itsAClass a1 = new itsAClass();
System.out.println(a1.something());// prints This should be changed
}
}

On reload of page, mvp4g history mechanism fails

I have implemented a history mechanism for my mvp4g project. When I traverse through the pages, I can see the url also getting changed. But on reload of any page other than home page, always home page gets displayed instead of the desired page?
This is my implementation:
#History(type = HistoryConverterType.SIMPLE)
public class CustomHistoryConverter implements HistoryConverter<AppEventBus> {
private CustomEventBus eventBus;
#Override
public void convertFromToken(String historyName, String param, CustomEventBus eventBus) {
this.eventBus = eventBus;
eventBus.dispatch(historyName, param);
}
public String convertToToken(String eventName, String name) {
return name;
}
public String convertToToken(String eventName) {
return eventName;
}
public String convertToToken(String eventName, String name, String type) {
return name;
}
public boolean isCrawlable() {
return false;
}
}
and event bus related code :
#Events(startPresenter=PageOnePresenter.class,historyOnStart=true)
public interface CustomEventBus extends EventBusWithLookup {
#Start
#Event(handlers = PageOnePresenter.class)
void start();
#InitHistory
#Event(handlers = PageOnePresenter.class)
void init();
#Event(handlers = PageTwoPresenter.class, name = "page2", historyConverter = CustomHistoryConverter.class)
void getPageTwo();
#Event(handlers = PageThreePresenter.class, name = "page3", historyConverter=CustomHistoryConverter.class)
void getPageThree();
#Event(handlers=PageOnePresenter.class, name = "page1", historyConverter=CustomHistoryConverter.class)
void getPageOne();
#Event(handlers=PageOnePresenter.class)
void setPageTwo(HistoryPageTwoView view);
#Event(handlers=PageOnePresenter.class)
void setPageThree(HistoryPageThreeView view);
}
The HistoryConverter needs to be improved.
In fact, that the event has no parameter, you should return an empty string. Update the HistoryConverter that it looks like that:
#History(type = HistoryConverterType.SIMPLE)
public class CustomHistoryConverter implements HistoryConverter<AppEventBus> {
private CustomEventBus eventBus;
#Override
public void convertFromToken(String historyName, String param, CustomEventBus eventBus) {
this.eventBus = eventBus;
// TODO handle the param in cases where you have more than one parameter
eventBus.dispatch(historyName, param);
}
public String convertToToken(String eventName, String name) {
return name;
}
public String convertToToken(String eventName) {
return "";
}
public String convertToToken(String eventName, String name, String type) {
return name - "-!-" type;
}
public boolean isCrawlable() {
return false;
}
}
Hope that helps.

Passing a variable from parent to child class in Java

I am completely new to Java... :(
I need to pass a variable from a parent class to a child class, but I don't know how to do that.
The variable is located in a method in the parent class and I want to use it in one of the methods of the child class.
How is this done?
public class CSVData {
private static final String FILE_PATH="D:\\eclipse\\250.csv";
#Test
public static void main() throws IOException {
//some code here
String firstname1 = array.get(2).get(1);
}
}
and then the other class
public class UserClassExperimental3 extends CSVData {
public static void userSignup() throws InterruptedException {
//some code here
String firstname= firstname1; //and here it doesnt work
}
}
Actually I think I succeeded doing that this way:
added the variable here:
public static void userSignup(String firstname1)
then used it here:
String firstname=firstname1;
System.out.println(firstname);
But now I can't pass it to the method that needs it.
The variable firstname1 is a local variable. You can't access it outside its scope - the method.
What you can do is pass a copy of the reference to your subclass.
Since you're calling a static method, the easiest way is to pass the reference as an argument to the method call:
#Test
public static void main() throws IOException {
//some code here
String firstname1 = array.get(2).get(1);
UserClassExperimental3.userSignup( firstName1 );
}
public class UserClassExperimental3 extends CSVData {
public static void userSignup( String firstNameArg ) throws InterruptedException {
//some code here
String firstname = firstnameArg; // Now it works
}
}
That said, since you're using inheritance, you might find it useful to use an instance method. Remove "static" from the method. In main(), construct an instance of the class, provide it the name, and call the method on the instance.
#Test
public static void main() throws IOException {
//some code here
String firstname1 = array.get(2).get(1);
UserClassExperimental3 instance = new UserClassExperimental3( firstName1 );
instance.userSignup();
}
public class UserClassExperimental3 extends CSVData {
private String m_firstName;
public UserClassExperimental3( String firstName ) {
m_firstName = firstName;
}
public void userSignup() throws InterruptedException {
//some code here
String firstname = m_firstname; // Now it works
}
}
If you also add userSignup() to the CSVData class, you can refer to the specific subclass only on creation. This makes it easier to switch the implementation, and it makes it easier to write code that works regardless of which subclass you're using.
String firstname1 = array.get(2).get(1);
CSVData instance = new UserClassExperimental3( firstName1 );
instance.userSignup();
public class Main {
public static void main(String[] args) {
User user=new User();
user.setId(1);
user.setName("user");
user.setEmail("user#email.com");
user.save();
}
}
public class User extends Model {
private int id;
private String name;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
import java.lang.reflect.Field;
public class Model {
public void save(){
for(Field field: Model.this.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
System.out.println(field.getName()+"="+field.get(Model.this));
} catch (Exception ex) {
ex.printStackTrace();
}
}
return;
}
}

java - reflection: How to Override private static abstract inner class method?

I have the following class:
class MyClass{
private static final int VERSION_VALUE = 8;
private static final String VERSION_KEY = "versionName";
public boolean myPublicMethod(String str) {
try {
return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
new MyInnerClass() {
#Override
public InputStream loadResource(String name) {
//do something important
}
});
}
catch (Exception e) {
}
return false;
}
private boolean myPrivateMethod(String str, String key, int version,
ResourceLoader resourceLoader) throws Exception
{
//do something
}
private static abstract class MyInnerClass {
public abstract InputStream loadResource(String name);
}
}
I want to write unit test for myPrivateMethod for which I need to pass resourceLoader object and override it's loadResource method.
Here is my test method:
#Test
public void testMyPrivateMethod() throws Exception {
Class<?> cls = Class.forName("my.pack.MyClass$MyInnerClass");
Method method = cls.getDeclaredMethod("loadResource", String.class);
//create inner class instance and override method
Whitebox.invokeMethod(myClassObject, "testValue1", "testValue2", "name1", 10, innerClassObject);
}
Note, that I can't change code.
Well, you could use Javassist...
See this question. I haven't tried this, but you can call this method when you want the override:
public <T extends Object> T getOverride(Class<T> cls, MethodHandler handler) {
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(cls);
factory.setFilter(
new MethodFilter() {
#Override
public boolean isHandled(Method method) {
return Modifier.isAbstract(method.getModifiers());
}
}
);
return (T) factory.create(new Class<?>[0], new Object[0], handler);
}
Well, the problem i see with your code is that you are calling myPublicMethod and you are giving fourth parameter as new MyInnerClass(). Now in your private method fourth parameter is given as ResourceLoader and from your code i see no relation between MyInnerClass and ResourceLoader. So you can try out following code. It might help.
Despite your warning that you cannot change the code i have changed it because i was trying to run your code.
class MyClass{
private static final int VERSION_VALUE = 8;
private static final String VERSION_KEY = "versionName";
public boolean myPublicMethod(String str) {
try {
return myPrivateMethod(str, VERSION_KEY, VERSION_VALUE,
new MyInnerClass() {
#Override
public InputStream loadResource(String name) {
return null;
//do something important
}
});
}
catch (Exception e) {
}
return false;
}
private boolean myPrivateMethod(String str, String key, int version,
MyInnerClass resourceLoader) throws Exception
{
return false;
//do something
}
private static abstract class MyInnerClass {
public abstract InputStream loadResource(String name);
}
}
Hope it helps.

Categories

Resources