originally had the code below
public class Sender {
public void printLine() {
System.out.println("print line");
}
}
public class BSending {
protected final Sender aSender;
private final RandomNumGen randomNumGen;
@Autowired
public BSending(Sender sender, int thresh) {
this.aSender = sender;
this.randomNumGen = new RandomNumGen(thresh);
//also injects other beans
}
public void sendTask() {
if (this.randomNumGen.isChosen()) {
aSender.printLine();
}
}
}
public class BSendingTest {
@Mock private Sender aSender;
@Mock private RandomNumGen randomNumGen;
@Test
void test() {
when(randomNumGen.isChosen()).thenReturn(true);
BSending bSending = new BSending(aSender, 25);
bSending.sendTask();
verify(aSender, times(1)).printLine();
}
}
end2endTest {
..
@SpringBootTest(
classes = {
BSending.class
})
..
}
where randomNumGen.isChosen()
uses a random-number generator to determine if it should return true or false,
but it depends on the value thresh
that is passed into BSending
. This value is read from an input text file
Here, I expected aSender.printLine()
to be hit, but its not. Its because the mocked randomNumGen
isn't being used due to the new RandomNumGen(thresh)
EDIT:
If I then create an abstract class Conf
so the now becomes
@Component
public abstract class Conf {
public int thresh;
public abstract RandomNumGen newRandomNumGen();
}
public class BSending {
protected final Sender aSender;
private final Conf conf;
@Autowired
public BSending(Sender sender, int thresh, Conf conf) {
this.aSender = sender;
this.conf = conf;
this.conf.thresh = thresh;
}
public void sendTask() {
if (conf.randomNumGen.isChosen()) {
aSender.printLine();
}
}
}
public class BSendingTest {
@Mock private Sender aSender;
@Mock private RandomNumGen randomNumGen;
@Mock private Conf conf;
@Test
void test() {
when(conf.newRandomNumGen()).thenReturn(randomNumGen);
when(randomNumGen.isChosen()).thenReturn(true);
BSending bSending = new BSending(aSender, 25, conf);
bSending.sendTask();
verify(aSender, times(1)).printLine();
}
}
where randomNumGen.isChosen()
uses a random-number generator to determine if it should return true or false
Before, I expected aSender.printLine()
to be hit, but its not. But with this new code with the abstract class Conf
, now it works.
The problem now is that because Conf
is an abstract class (I made it abstract because it has the thresh
member and newRandomGen()
method), the end2end test now fails with BeanInstantiationException is it an abstract class
as it has
@SpringBootTest(
classes = {
BSending.class, Conf.class
})
Is there a way I can replicate the above without having to make Conf
an abstract class?
EDIT2:
public class RandomNumGen {
private final thresh;
public RandomNumGen(int thresh) {
this.thresh = thresh;
}
public boolean isChosen() {
return isChosenX(this.thresh, new Random())
}
public boolean isChosenX(int thresh, Random random) {
//determine if chosen using random number generator and thresh
}
}