Imagine I have the following class structures:
public interface Sender {
void send(String note);
}
public interface Agent {
void sendNote(String note);
}
public class Emailer implements Sender {
void send(String note) {
//...do something
}
}
public class Helper {
List<String> populateNotes() {
//...do something
}
}
public class EmailAgent implements Agent {
List<String> notes;
void sendNote(String note) {
Helper helper = new Helper();
notes = helper.populateNotes();
for (String s : notes) {
Sender sender = new Emailer();
sender.send(s);
}
}
}
Now, I want to unit test the sendNote() method in EmailAgent. However, there is a dependency on Helper as it needs to populate the list notes. If in the JUnit test I first call populateNotes() before calling sendNote()...
Is this a unit test or acceptance test?
Or should I hard coded the list?
Or use suggestion 2 - create a stub producing a hard-coded list - then unit test the sendNote method. Mocking would also help with this but requires coding against interfaces to be of any use. While it will work, a simple stub should also do the trick.
Related
I have a class for which I am writing a JUnit test. I am trying to test if a particular method is never called.
public class CountryProcess extends AbstractCountryProcess {
private static final Logger log = LoggerFactory.getLogger(CountryProcessor.class);
private static final Long MAX_FILE = 20l;
#Override
protected boolean processCountry(Region region, City city) {
Long maxFile = region.getRequiredLongValue(SIZE);
if (maxFile < MAX_FILE) {
cntDao.addCountryLandMark(city);
}
else {
log.warn("File size was big");
}
return true;
}
And the test class is:
public class CountryProcessTest {
#Rule
public final JUnitRuleMockery context = new JUnitRuleMockery();
private final CntDao cntDao = context.mock(CntDao.class);
#Before
public void setup() {
Injector injector = Guice.createInjector(new AbstractModule() {
#Override
protected void configure() {
bind(cntDao.class).toInstance(cntDao);
}
});
}
#Test
public void shouldIgnoreIfFileSizeBiggerThanPermitted() {
//some code to make it trigger ELSE statement above...
verify(cntDao, never()).addCountryLandMark(anyString());
}
}
But this returns the following error:
org.mockito.exceptions.misusing.NotAMockException:
Argument passed to verify() is of type $Proxy4 and is not a mock!
Make sure you place the parenthesis correctly!
See the examples of correct verifications:
verify(mock).someMethod();
verify(mock, times(10)).someMethod();
verify(mock, atLeastOnce()).someMethod();
Any idea how I can fix this in the current context. Please give an example using current code so I get a better idea?
You are mixing two mocking frameworks:
jMock - JUnitRuleMockery
Mockito - verify method
Clearly, they are not compatible with each other.
Your verify call looks ok, I believe it will work as soon as it receives a mock created with Mockito (Use Mockito.mock(CntDao.class))
As an alternative to never you can use Mockito.verifyNoMoreInteractions or Mockito.verifyZeroInteractions, but they are less specific.
In addition to the answer from #Lesiak, here is a reproducible example based on your code with both conditions tested and BDD implementation as well (commented out).
#ExtendWith(MockitoExtension.class)
class CountryProcessTest {
#Mock CountryDAO cntDao;
#Mock
Region region;
#Mock
City city;
#InjectMocks
CountryProcess countryProcess;
#Test
void processCountryLargeSize() {
// given
given(region.getRequiredLongValue()).willReturn(100L);
// when
countryProcess.processCountry(region, city);
// then
verifyNoInteractions(cntDao);
// then(cntDao).shouldHaveNoInteractions(); // BDD implementation
}
#Test
void processCountrySmallSize() {
// given
given(region.getRequiredLongValue()).willReturn(10L);
// when
countryProcess.processCountry(region, city);
// then
verify(cntDao).addCountryLandMark(city);
verifyNoMoreInteractions(cntDao);
// then(cntDao).should().addCountryLandMark(any()); // BDD implementation
// then(cntDao).shouldHaveNoMoreInteractions(); // BDD implementation
}
}
The rest of the classes here are provided for reference.
Region
public class Region {
private int size;
public Long getRequiredLongValue() {
return Integer.toUnsignedLong(size);
}
}
AbstractCountryProcess
public abstract class AbstractCountryProcess {
CountryDAO cntDao;
protected abstract boolean processCountry(Region region, City city);
}
For the sample code below...
Is there a way to chain instances of different classes? The example provided is a failed attempt for wiring up methods belonging to different class instances.
Also, In the same example, Client2 is sharing the error object with Client3. What is a more efficient way of sharing objects between subclasses and unassociated classes?
For clarity, i have also commented inline.
Thank You for your time and help.
Sample Code
public class StubRunner
{
public run(){
ClientFactory client = new ClientFactory();
//not correct. But, this is how i want to finally chain methods
//belonging to different class instances. Please advise.
client.getClient1().testClient1().getClient2().testClient2().assert(...);
}
}
public class ClientFactory
{
public Client1 getClient1(){return new Client1();}
public Client2 getClient2(){return new Client2();}
}
public class BaseClient
{
public Errors errors = null;
}
public class Client1 extends BaseClient
{
public void testClient1(){...}
}
public class Client2 extends BaseClient
{
public void testClient2()
{
//here i am directly passing the error object
//what is a better way?
//is there a more efficient way to make the SAME error object
//available to Client3
new Client3(this.errors).testClient3();
...
}
}
public class Client3 extends BaseClient
{
public Client3(Errors errors){this.errors = errors;}
public void testClient3(){...}
}
I would normally use lambda expressions for the cases when I want to program a short chain of method calls but I want the methods to change relatively to any kind of state. As for your scenario, each of your test would be a lambda expression and it would mean that I would pass the testClient4 method to the testClient3 method, the testClient3 method to the testClient2 method, etc. However, the code becomes more and more ugly as your chain of method calls becomes long.
=> You can use Fluent interface: you would have each method doing some logic and then returning an instance on which you can call the next inline methods you want to execute.
ClientFactory.getClient1() : Client1
Client1.testClient1() : Client1 (i.e. return this)
Client1.getClient2() : Client2
Client2.testClient2() Client2 (i.e. return this)
...
Obviously, each instance would need to have a reference to the next inline instance, knowing the one it will call (Client1 would have a reference to Client2, Client2 to Client3, etc).
This would work but I'm not a fan in this scenario! I'd say it's more a trick than clean coding. You should use fluent interface with each client separately unless one of your method is actually returning another instance:
client1.testClient1().testClient2().testClient3()
with each test method returning an instance of the next client if there is a good reason for it
but it wouldn't make sense to interpose the getClient methods between the test methods...
I am not really getting what your need really is, however in the actual state of the code it cannot even compile since you are trying to execute methods from a "Client" object from a void method return.
If you do not know how many clients and from which type you are going to get, I would simply use a list.
If you want to chain the clients using the 'testClient' method, then first this method should return the next client (which is a really awkward way to chain objects by the way), then you should start using more abstraction and overriding technics.
Basically, there's no need to know what object you are dealing with as long as it is a "BaseClient", but if you name the child methods "testClient1", "testClient2" etc ... you basically breaking it and you need to start thinking of what you are actually getting and adapt your code accordingly.
Finally, there's no need for a factory here, but if you want one, it should be static.
Here is a working example of this, again I do not really comprehend what you wanna do so it may not solve your issue, but it's a working solution to "chaining instances":
Main:
public class Foo
{
// arguments are passed using the text field below this editor
public static void main(String[] args)
{
StubRunner stub = new StubRunner();
stub.run();
}
}
Stubrunner:
public class StubRunner implements Runnable
{
public void run(){
Object clients = ClientFactory.getClient1();
while (null!= clients && clients instanceof BaseClient) {
clients = ((BaseClient) clients).test();
}
}
}
Base:
public abstract class BaseClient
{
public Exception errors = null;
public BaseClient() {};
public BaseClient(Exception errors) {
this.errors = errors;
}
public abstract BaseClient test();
public void checkErrors() {
System.out.println(this.toString());
assert null == errors;
}
}
Client 1:
public class Client1 extends BaseClient
{
public BaseClient test(){
checkErrors();
return new Client2();
}
}
Client 2:
public class Client2 extends BaseClient
{
public BaseClient test()
{
checkErrors();
return new Client3(this.errors);
}
}
Client 3:
public class Client3 extends BaseClient
{
public Client3(Exception errors) {
super(errors);
}
public BaseClient test() {
checkErrors();
return null;
}
}
Factory:
public final class ClientFactory
{
private ClientFactory() {};
public static Client1 getClient1(){return new Client1();}
public static Client2 getClient2(){return new Client2();}
}
This outputs the following:
test.Client1#15db9742
test.Client2#6d06d69c
test.Client3#7852e922
Is there a way to chain instances of different classes? The example provided is a failed attempt for wiring up methods belonging to different class instances.
client.getClient1().testClient1().getClient2().testClient2().assert(...);
In order to chain methods like this, each method must return a reference to an object which supports the method which you want to call. However, each test method returns void.
In this case, method chaining seems very questionable because you are operating on different types. Often methods in a chain like this will just return this; so that another method can be called on the exact same object which started the chain.
Additionally, the names of your methods suggest that you are attempting to implement some automated testing of your code. You should learn about established testing techniques and libraries. In particular, JUnit is commonly used in Java and variations in other languages. There are certain techniques that are considered good practice when writing tests in frameworks such as this.
To be clear here, you should certainly not mix testing code with production code.
Also, In the same example, Client2 is sharing the error object with Client3. What is a more efficient way of sharing objects between subclasses and unassociated classes?
//here i am directly passing the error object
//what is a better way?
//is there a more efficient way to make the SAME error object
//available to Client3
new Client3(this.errors).testClient3();
The only way to send an object to a class is to pass a parameter, either to the constructor or to a method. This is how Java works.
Note that there is very little overhead because you are passing a reference variable. You are not copying the entire object. This means that both the current instance of Client2 and the new instance of Client3 have references to the same error object.
Now testClient1() could return the client factory and such. But that is very convoluted.
Another regulatory syntax is to override a context providing class.
new ClientFactory() {{
getClient1().testClient1();
getClient2().testClient2().assert(...);
}};
Here an initializing block ("anonymous constructor") will provide a context.
Then a bit of chaining can be done when testClient2 returns a Client2.
It can be a clean and useful design, for instance for my ambiguous grammar parser AnyParser on sourceforge.net (purely a craftmanship piece of work).
Thank you everyone for the great help. Your advise has allowed me to arrive at the following working solution. Maybe it is not the best, so seeking your valuable time and your expertise to direct to a better solution.
Given some remarks my naming convention being fishy, i have tried to amend them to a certain extent. Kindly bear with me.
Objective was:
To chain instances of different classes
To share objects between subclasses and unassociated classes
Problem description:
There are 4 tasks to be performed: Task1 to Task4.
Each task is unique. But sometimes, to complete a task we need to perform mixed Task: refer Task3 >> performMixedTasks()
To complete a piece of work we need to complete a set of Tasks.
State.java
public class State {
public Boolean ISAUDITED = false;
public int ERRORCODE = 0;
public String ERRORTEXT = "";
public void raise(int code, String msg){
this.ERRORCODE = code;
this.ERRORTEXT = msg;
}
}
BaseClient.java
public abstract class BaseClient {
public State state;
public BaseClient(){
this.state = new State();
}
public BaseClient(State state){
this.state = state;
}
public ClientFactory getTest(){
return new ClientFactory(state);
}
public Boolean Assert(){
if(state.ERRORCODE == 0){
System.out.println("Parsing was successful.");
return true;
}
else{
System.out.println("Parsing was not successful.");
return false;
}
}
public abstract BaseClient GoTo();
}
Task1.java
public class Task1 extends BaseClient {
public Task1(){ GoTo(); }
public Task1(State state){ super(state); GoTo(); }
public Task1 performTask1(){
if(!state.ISAUDITED)
{
System.out.println("perform Task1");
state.ISAUDITED = true;
}
return this;
}
#Override
public BaseClient GoTo() {
if(state.ISAUDITED){
new Task2(state).performTask2();
}
return this;
}
}
Task2.java
public class Task2 extends BaseClient{
public Task2(){ GoTo(); }
public Task2(State state){ super(state); GoTo(); }
public Task2 performTask2(){
if(state.ISAUDITED)
{
System.out.println("perform Task2");
state.ISAUDITED = false;
}
return this;
}
#Override
public BaseClient GoTo() {
if(!state.ISAUDITED){
new Task1().performTask1();
}
return this;
}
}
Task3.java
public class Task3 extends BaseClient {
public Task3(){ }
public Task3(State state){ super(state); }
public Task3 GoTo(){
if(!state.ISAUDITED) {new Task1(state).performTask1();}
System.out.println("Opening Task3");
return this;
}
public Task3 performTask3(){
try
{
this.GoTo();
System.out.println("Submitted Task3 Data");
}
catch(Exception e){
state.raise(1, e.getMessage());
}
return this;
}
public Task3 performMixedTasks(){
new Task4(state).performTask4();
this.performTask3();
return this;
}
}
Task4.java
public class Task4 extends BaseClient {
public Task4(){ }
public Task4(State state){ super(state); }
public Task4 GoTo(){
if(!state.ISAUDITED) {new Task1(state).performTask1();}
System.out.println("Opening Task 4");
return this;
}
public Task4 performTask4(){
try
{
this.GoTo();
System.out.println("Submitted Task 4 Data");
}
catch(Exception e){
state.raise(1, e.getMessage());
}
return this;
}
}
ClientFactory.java
public class ClientFactory {
State state;
public ClientFactory(){
state = new State();
}
public ClientFactory(State state){
this.state = state;
}
public Task3 loadTask3(){return new Task3(state);}
public Task4 loadTask4(){return new Task4(state);}
}
StubRunner1.java
public class StubRunner1 {
public static void main(String[] arg)
{
ClientFactory test = new ClientFactory();
test.loadTask3()
.performTask3()
.getTest()
.loadTask4()
.performTask4()
.Assert();
}
}
**RESULT IS**
perform Task1
Opening Task3
Submitted Task3 Data
Opening Task4
Submitted Task4 Data
Parsing was successful.
StubRunner2.java
public class StubRunner2 {
public static void main(String[] args) {
ClientFactory test = new ClientFactory();
test.loadTask3()
.performMixedTasks()
.Assert();
}
}
**RESULT IS**
perform Task1
Opening Task4
Submitted Task4 Data
Opening Task3
Submitted Task3 Data
Parsing was successful.
I have Utils class with method which throws exception when given data are incorrect.
I have also Service which uses this method, but the data are always generated in way that they will be correct during call. Data are generated by another utils class.
I understand that I should throw this exception from Utils class - but I can't throw it from Service - so I have to catch it.
How can I test this, simulate this exception?
All actions on this data are in private methods.
I want to avoid PowerMock, because I heard that it's a sign of bad design.
So the question is, how to implement this in good design?
From your description it looks like this:
class Service {
public void someMethod() {
Data data = AnotherUtils.getData();
try {
Utils.method(data); // exception never thrown
} catch(Exception e) {
// how to test this branch?
}
}
}
The goal would be something like this:
interface DataProvider {
Data getData();
}
interface DataConsumer {
void method(Data data);
}
class Service {
private final DataProvider dataProvider;
private final DataConsumer dataConsumer;
public Service(DataProvider dataProvider, DataConsumer dataConsumer) {...}
public void someMethod() {
Data d = dataProvider.getData();
try {
dataConsumer.method(data);
} catch(Exception e) {
}
}
}
This technique is called dependency injection.
Then, when testing, you can simply provide a mock implementation for this DataProvider interface that does return faulty data:
#Test(expected=Exception.class)
public void myTest() {
DataProvider badDataProvider = () -> new BadData(); // Returns faulty data
Service service = new Service(badDataProvider, Utils.getConsumer());
service.someMethod(); // boom!
}
For the non-testing code, you could simply wrap the utils classes you already have in these interfaces:
class AnotherUtils {
public static Data getData() {...}
public static DataProvider getProvider() {
return AnotherUtils::getData;
}
}
...
Service service = new Service(AnotherUtils.getProvider(), Utils.getConsumer());
Here is an approach where you want to introduce Dependency Injection, but for whatever reason you don't want to change legacy code.
Say you have some static utility method like so:
class Utils{
public static Something aMethod(SomethingElse input) throws AnException{
if(input.isValid())
return input.toSomething();
throw new AnException("yadda yadda");
}
}
And you have a class that uses that utility method. You can still inject it with a FunctionalInterface.
#FunctionalInterface
interface FunctionThrowsAnException<K,V> {
V apply(K input) throws AnException;
}
class Service {
private final FunctionThrowsAnException<SomethingElse,Something> func;
Service(FunctionThrowsAnException<SomethingElse,Something> func){
this.func = func;
}
Something aMethod(SomethingElse input){
try{
return func.apply(input);
}catch(AnException ex){
LOGGER.error(ex);
}
}
}
Then use it like this:
new Service(Utils::aMethod).aMethod(input);
To test it:
new Service(x -> { throw new AnException("HA HA"); }).aMethod(input);
I have my database layer:
public class DataBaseLayer
{
public Result runQuery(Query q)
{
this.openSession();
this.runPackage(q);
Results r = this.fetchResults();
this.closeSession();
return r;
}
}
Currently all those methods are private methods.
But I want to be able to test them.
for example
private void testOpenSession_wrongUserNamePassword_returnsBadUserNamePassWordError();
private void testrunPackage_insufficientPrivileges_returnsInsufficientPrivlegesError();
The question is what's the nicest way of doing this?
I figure I could either:
Just test the runQuery method for bad username password etc.
Make those methods protected.
Make those methods public.
I assume your class is using some collaborator to connect to the database when you call this.openSession() mock that collaborator and have the mock return the responses desired for bad password or insufficient privileges so you can test the behaviour of your class in that scenario. eg
class under test
public class DataBaseLayer {
public DataBaseLayer(SomeDBClass dbObject){
this.dbObject = dbObject;
}
...
private void openSession() {
dbObject.connect(username, password);
}
...
public Result runQuery(Query q){
...
}
test class
public class DataBaseLayerTest {
#Test(expected = IncorrectPasswordException.class)
public void testOpenSession_wrongUserNamePassword_returnsBadUserNamePassWordError() {
SomeDBClass someDBClass = Mockito.mock(SomeDBClass.class)
Mockito.when(someDBClass.connect(Mockito.anyString(), Mockito.anyString())).throw(new IncorrectPasswordException())
DataBaseLayer underTest = new DataBaseLayer(someDBClass)
underTest.runQuery(someQuery);
}
}
I think I might have found a bug in JMockit, but I would like some to confirm whether it's a bug or there's something I'm missing.
I have the following (very simple) class:
public class Dummy {
public void foo() {System.out.println("O");}
}
Now I have the following tests, where in each of them I try to mock the method 'foo' more than once (each test does it a little differently):
Test #1
#Test
public void test1() {
new MockUp<Dummy>() {
#Mock
public void foo(Invocation inv) {
System.out.println("A");
inv.proceed();
}
}
new MockUp<Dummy>() {
#Mock
public void foo(Invocation inv) {
System.out.println("B");
inv.proceed();
}
}
new Dummy().foo();
}
Test #2
#Test
public void test2() {
mock("A");
mock("B");
new Dummy().foo();
}
private void mock(final String s) {
new MockUp<Dummy>() {
#Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
The only difference between the tests is the extraction of the mock code to a different method. But the results are not the same...
Test #1 output:
B
A
B
O
This is odd, because I wouldn't expect A to appear at all. But anyway, here's test #2 output:
B
A
A
A
...ad infinitum
Test #2 will fail with a StackOverflowError.
Is this a bug or am I missing something?
Update (with the solution)
As #Rogério mentioned, this behavior is not acceptable.
Then how can the mock be overridden? like this:
private MockUp<Dummy> mock;
#Test
public void test3() {
mockCorrectly("A");
mockCorrectly("B");
new Dummy().foo();
}
private void mockCorrectly(final String s) {
if (mock != null) {
mock.tearDown();
}
mock = new MockUp<Dummy> {
#Mock
public void foo(Invocation inv) {
System.out.println(s);
inv.proceed();
}
}
}
And for the output:
B
O
Great :)
It's not clear what exactly happens here; apparently, at runtime some "chained mocking" is occurring.
The real problem is that both tests are doing something invalid with the MockUp API: they are mocking the same method in the same class twice in the same test. It is ok to have two different mock-ups for the same class in the same test, as long as they mock different methods/constructors.
The resulting behavior is undefined, as JMockit does not support multiple simultaneous mockings of the same method.