Truncate the method in java - java

I have the following code:
public class Search {
private Desktop desktop = new Desktop();
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
baseState.execute(desktop);
}
#Test
public void searchNames() {
desktop.<BrowserApplication>find("//BrowserApplication").<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
}
}
I was able to truncate the Test method to this:
public class Search {
private Desktop desktop = new Desktop();
BrowserApplication app;
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
app = baseState.execute(desktop);
}
#Test
public void searchNames() {
app.<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
}
How do I truncate the method even further? I would like to be able to use something like this:
win.<DomButton>find("//INPUT[#id='edit-submit']").select();
instead of this chunky long:
desktop.<BrowserApplication>find("//BrowserApplication").<BrowserWindow>find("//BrowserWindow").<DomButton>find("//INPUT[#id='edit-submit']").select();
Please paste the whole class in your response?

public class Search {
private Desktop desktop = new Desktop();
BrowserWindow win;
#Before
public void baseState() {
BrowserBaseState baseState = new BrowserBaseState("silk4j.settings");
win = baseState.execute(desktop).find("//BrowserWindow");
}
#Test
public void searchNames() {
win.<DomButton>find("//INPUT[#id='edit-submit']").select();
}
}

Related

Testing for class field with is share among methods

I have a Java class as follow
public class MyClass {
private final ShowFactory showFactory;
private SomeShow someShow;
public MyClass(ShowFactory showFactory) {
this.showFactory = showFactory;
startShow();
}
public void startShow() {
someShow = showFactory.createShow();
someShow.start();
}
public void showSomething() {
MagicBox magicBox = new MagicBox();
someShow.showSomething(magicBox);
}
public void stopShow() {
someShow.stop();
}
}
and trying to test showSomething method. Complete test file is as follow
public class MyClassTest {
private ShowFactory showFactory;
private SomeShow someShow;
#Before
public void setUp() {
showFactory = mock(ShowFactory.class);
someShow = mock(SomeShow.class);
when(showFactory.createShow()).thenReturn(someShow);
}
#Test
public void shouldStartShow() {
new MyClass(showFactory);
verify(someShow).start();
}
#Test
public void shouldShowSomething() throws Exception {
MagicBox magicBox = mock(MagicBox.class);
PowerMockito.whenNew(MagicBox.class).withAnyArguments().thenReturn(magicBox);
doNothing().when(someShow).showSomething(magicBox);
InOrder inOrder = inOrder(someShow);
MyClass myClass = new MyClass(showFactory);
myClass.showSomething();
inOrder.verify(someShow).start();
inOrder.verify(someShow).showSomething(magicBox);
}
#Test
public void shouldStopShow() {
MyClass myClass = new MyClass(showFactory);
myClass.stopShow();
verify(someShow).start();
verify(someShow).stop();
}
}
But test shouldShowSomething is failing with error Wanted but not invoked. Any thing I am missing here? Any suggestion?
It was simple fix. After reading through https://github.com/powermock/powermock/wiki/MockConstructor#quick-summary (thanks to #roby) turns out I was missing the #PrepareForTest annotation for the class.
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClass.class)
public class MyClassTest {
...
}

NoSuchField error in java code but field exists

I have the following code.
public class Table {
Integer[] data;
public Table() {
this.data = new Integer[100];
}
public boolean insert(int key){
data[53] = 1;
return true;
}
}
&&
public class test{
private Table tab;
protected void setUp() throws Exception {
tab = new Table();
}
public void testInsertTable() {
tab.insert(1);
assertTrue(tab.data[53] == 1); // error here
}
}
The test class is run using JUnit.
The code works when i run in it Eclipse but i get a NoSuchField error on the line pointed by the comment when i run it outside of Eclipse.
The class responsible for the problem is Table, that much i know for certain.
What could be wrong is you are not using #Before annotation on the setup method
The correct code should be
public class test{
private Table tab;
#Before
protected void setUp() throws Exception {
tab = new Table();
}
#Test
public void testInsertTable() {
tab.insert(1);
assertTrue(tab.data[53] == 1); // error here
}
}

Repeat JUnit tests run with different setup

For example I have some tests based on Set<Integer>. I want to run them with TreeSet and then with HashSet. Can I do it without manual initialization inside test method body?
Something like this:
public class SomeTest {
Set<Integer> set;
#Before
public void init() {
set = new HashSet<>();
}
// #Before
// public void init2() {
// set = new TreeSet<>();
// }
//test...
}
I want to run all tests with init() first and then with init2(). How can I do it?
A cleaner approach would be:
public abstract class SomeTestsForSets {
Set<Integer> set;
#Before
public abstract void init();
//test cases...
}
public class HashSetTests extends SomeTestsForSets {
#Override
public void init() {
this.set = new HashSet<>();
}
}
public class TreeSetTests extends SomeTestsForSets {
#Override
public void init() {
this.set = new TreeSet<>();
}
}

how to "pull down" a parameter when refactor in eclipse?

before refactor:
public interface Service {
public void hello(Person p);
}
public class BlackPersonServiceImpl implements Service {
#Override
public void hello(Person p) {
//...
}
}
public class WhitePersonServiceImpl implements Service {
#Override
public void hello(Person p) {
//...
}
}
public class BeforeRefactor {
public static void main(String[] args) {
String str = args[0];
Person p = JSON.parseObject(str, Person.class);
Service service = getServiceFromSpringContainer();
service.hello(p);
}
private static Service getServiceFromSpringContainer() {
//...
return null;
}
}
after refactor:
public interface Service {
public void hello(String str);
}
public class WhitePersonServiceImpl implements Service {
#Override
public void hello(String str) {
Person person = JSON.parseObject(str, Person.class);
//do something to person...
//...
}
}
public class AfterRefactor {
public static void main(String[] args) {
String str = args[0];
Service service = getServiceFromSpringContainer();
service.hello(str);
}
private static Service getServiceFromSpringContainer() {
//...
return null;
}
}
That's what I want(I think "pull down" is not the "right" word to describe it...).
I tried "introduce parameter object" in eclipse, and it does not work.
There are many implementations of "Service". I dont want to change them one by one.
Is there a good way to solve this problem?
Thanks!
You can do it somewhat for a single class and a single method (although it's akward and a succession of small refactoring steps), but not across several types at the same time.

Checking passed params in unit testing with Mockito

I am trying to write really simple test with Mockito. I wrote small piece of code:
public class FlowTests {
#Mock
Calculator mockCalc = Mockito.mock(Calculator.class);
ConsoleView mockView = Mockito.mock(ConsoleView.class);
#Test
public void a01_Test() {
final String s = "2+2*2";
Controller c = new Controller();
c.setCalc(mockCalc);
Mockito.when(mockView.getFormule()).thenReturn(s); // I am not sure if it works
c.setView(mockView);
c.handle();
// TODO check if evaluate method has been invoked with "2+2*2"
}
}
Here you can see classes associated with this test:
public class Controller {
private IView view = new ConsoleView();
private ICalculator calc = new Calculator();
Double value = null;
public void handle() {
String formule = view.getFormule();
Double value = calc.evaluate(formule);
if (value != null) {
System.out.println("Result: ");
view.appendAnswer(value);
}
}
public void setCalc(ICalculator calc) {
this.calc = calc;
}
public void setView(IView view) {
this.view = view;
}
}
public class Calculator implements ICalculator {
public double evaluate(String s) {
...
char[] formuleChar = s.toCharArray();
result = calc.eval(formuleChar);
return result;
}
}
public class ConsoleView implements IView {
public String getFormule() {
... // getting s from console
return s;
}
public void appendAnswer(double r) {
System.out.println(r);
}
}
First goal of my test is to mock function getFormule() in ConsoleView to return always String s = "2+2*2". I did it but I am not sure if it works.
The main goal is to check if method evaluate() in Calculator class has been invoked with the same String. I have no idea how to that.
I cannot modify my code. I can only write a test.
Thank you in advance for your help!
Try something like this:
// check if evaluate method has been invoked with "2+2*2"
verify(mockCalc).evaluate("2+2*2");

Categories