JMock - Object without expectation - java

I'm using junt and jock.
Suppose I have an interface of an object, Contact, and a method like this one in my test class:
#Test
public void testAddOneContact() {
final Contact contact = this.context.mock(Contact.class);
this.addressBook.addContact(contact);
assertTrue("Object added to list", this.addressBook.getNumberOfContacts() == 1);
}
The method addContact is implemented in this way :
public void addContact(Contact contact) {
//Check if contact passed is valid. If it is, add it to address book
if(contact != null) {
this.contactsList.add(contact);
}
}
So you can see that I'm not calling any method of the Contact interface.
For this reason, I can't have any expectations in the test method testAddOneContact().
Is this a right way to implement a test case and use JMock (so even if I don't have any expectations)?

I will take a shot at this:.
Firstly, I do not see anything incorrect in the manner you have written the test.
Based upon the test case description I assume that the test case is for the AddressBook class which stores a list of contacts and that you are testing the method addContact exposed by the AddressBook class.
That said you can still make your class a bit more robust by doing something like below in the addContact method:
public void addContact(Contact contact) throws IllegalArgumentException
{
if(contact == null)
{
//throw an exception after logging that contact is null
throw new IllegalArgumentException("Passed in contact cannot be null!!")
}
this.contactsList.add(contact);
}
Now your test code for testAddOneContact will have to test two different input cases and this can be done as below using two separate test cases
#Test
public void testAddOneContact() {
final Contact contact = this.context.mock(Contact.class);
this.addressBook.addContact(contact);
assertTrue("Object added to list", this.addressBook.getNumberOfContacts() == 1);
//assuming that Contact class implements the equals() method you can test that the contact
//added is indeed the one that you passed in
assertTrue(addressBook.get(0).equals(contact));
}
//the below test ensures that there is exception handling mechanism within your library code
#Test
#Expected(IllegalArgumentException.class)
public void testShouldThrowWhenContactIsNull()
{
this.addressBook.addContact(null);
}
As an aside - Note how implementing a good test class makes you think about the design of the methods to be exposed as APIs and also how certain methods like hashCode and equals() need to be overridden. It also makes you think - 'how do I handle error cases?'. Such thoughtful questions are essential for ensuring that the code you are shipping solves exactly the problem which it is supposed to solve in an efficient and error-free manner.
Hope this helps

Related

Method Caller and Callee, circular class level method invocations

What are the problems with doing method caller and Callee of two different classes doing circular class level different method calls. You pass "this" reference, as a parameter to some other class instance method and the Callee doing further method invitation on caller which is passed as parameter.
One reason for doing that, In a factory class, Different implementations needs different kinds of data, so you put the data that is needed as multiple contracts/interface methods and have your caller implement them. If you have just one class it is easier to implement encapsulation, But different classes require different sets of data.
Following is simple example of such, Here StudentService calls MathClassScorer's topscorer method which in turn calls StudentService's getStudentList method. In a complex scenario, you might be calling multiple methods of parent caller.
public interface IStudentData {
public List<Student> getStudentList();
}
public class StudentService implements IStudentData {
private List<Student> studentList;
public String getTop() {
// Factory returns MathClassScorer
IScore scorer = ClassScorerFactory.get();
return scorer.topscorer(someOtherData, this);
}
#Override
public getStudentList() {
// do something and return studentList;
return studentList;
}
}
// IScore contains topscorer method
public class MathClassScorer implements IScore {
#Override
public String topscorer(Map someOtherData, IStudentData data) {
List<Student> studentList = data.getStudentList();
//do something before and after
return SOMETHING_AFTER
}
}
The Question is, Is there problem in the above approach ?
Well, the whole topic of OO is a bit controversial I'm afraid. But in my opinion the problems with the above code start with the naming of your classes. IStudentData is not an object. Holding some data is not a responsibility, and objects need responsibilities.
Then the design requires that the IScore objects know about the internal data content of the IStudentData, disregarding the object completely. The code also suggests that the IScore needs to know about the internal workings of Student too.
A good OO design is where objects actually have responsibilities, and their data is visible as little as possible, ideally not at all.
So, without knowing all the details, here is what your objects could look like:
public class Student {
public boolean isBetterAtMathThan(Student other) {
...
}
}
public class Students { // or StudentRepository
public Student getBestStudentAtMath() {
return students.stream().max(toComparator(Student::isBetterAtMathThan)).get();
}
}
Or, if you really want to generalize over a couple of different comparable skills, then you still can do that without exposing the data from Students:
public class Students {
public Student getBestStudentAt(Comparator<Student> skillComparator) {
return students.stream().max(skillComparator).get();
}
}
The point is, the Student should not expose data, but offer operations, or create other objects that can do stuff. Similarly, Students (the Service in your code) should not expose a list of students, instead it should provide methods to actually do stuff.
There are no problems with doing that. It is a common practice, known as the Strategy pattern.
Using injection like that is a very useful technique for decoupling logic, allowing unit testing of each component, by supplying mock objects.

Test a method without initialize the class

I'm very new to unit testing, I'm wondering if there is a way to test a method without initializing the class. The reason I'm asking is because there are lot of object passing in the constructor meaning a lot of mocking stubbing while from a thorough check methodToTest seems not to use any object attribute. It's not my code otherwise the method could be converted to static.
class ExampleClass {
public ExampleClass(FirstClass fc, SecondClass sc, ThirdClass tc) {}
public void methodToTest(FourthClass foc) {}
}
You have some options here:
Make the method static so you don't need a reference to an actual object. This will only work if the method does not need any state of ExampleClass (i.e. everything it needs is passed in the method arguments).
Extract this method to another class (perhaps using the method object pattern) that's easier to test on its own. This refactoring is called replace method with method object.
Usually, having to many parameters in constructors is a hint on bad conception. You'd better rethink you Objects and classes to reduce argument to give to the constructor.
If you don't want to, you can still use some kind of a "TestUtil" wich instantiate class for you.
Example :
public class MyTestUtils {
public createValidFirstClass() {
return new FirstClass(/* some arguments here */);
}
public createValidSecondClass() {
return new SecondClass(/* Some arguments here */);
}
public createValidThridClass() {
return new ThridClass(/* Some arguments here */);
}
public createValidExampleClass() {
return new ExampleClass(createValidFirstClass(), createValidSecondClass(), createValidThridClass());
}
}
This class MUST be in your test packages and not in your project, and should not be used outside of the tests, it would be a really bad practice here, use Factory or Builder for your real projects.
Anyway, i think that the best solution is to rethink you Classes.
Example :
public class People {
public People(String firstName, String lastName, Date birth, Date death) {
}
}
As you can see this is a pain in the ass to control that all given parameter was correctly formatted and not null.
This number of argument passed to a method can be reduced this way.
public class People {
public People(PeopleNames names, Period period) {
}
}
public class PeopleNames {
public People(String firstName, String lastName) {
}
}
public class PeopleNames {
public People(Date begin, Date end) {
}
}
Ok, it seems I found a way. Since the method is irrelevant to the state of the object, I could mock the object and order the MockRunner to use the real method when it is called. It is named partial mocking. The way of doing it is
ExampleClass = PowerMockito.mock(ExampleClass.class);
when(ExampleClass.methodToTest(foc)).thenCallRealMethod();
As far as I know, you cannot conduct a Test without initializing the class.
The three steps of Test are Arrange,Act and Assert. The class has to be initialized in the arrange part for fetching the required methods in the particular class you are testing.
I don't know what your method does but if it's possible for your application you could just make methodToTest static, which would allow you call it without an instance of the class.
Alternatively, you could avoid too much instantiation by creating one instance in a #BeforeClass method to be used for all tests, but again I don't know what you method does so that might not be desirable.
Use suppressions from PowerMockito.
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.api.support.membermodification.MemberMatcher;
suppress(MemberMatcher.constructor(ExampleClass.class))

Passing Two different Object type to a single Method in Java?

I try to follow this Stackoverflow post but it was not helping my purpose what I wanted to achieve. I want to know is it achievable in Java. Here is the problem statement. I tried to look into Java reflection, Haskel Either, etc. but it endup having two different objects.
I have two type of objects.
com.mobilesecuritycard.openmobileapi.Session msc_session;
org.simalliance.openmobileapi.Session sim_session
I want to have a method which accepts any of the two objects given above.
For example
public void runOperation(Object activeSession) {
activeSession.openLogicalChannel(APPLET_AID);
-- do the rest of operations ---
}
I want to use that function as given below
if(isSetSIMSessionTrue()){
Log.i(LOG_TAG, "Using SIM Session as its True");
sim_session = getSim_session();
runOperation((org.simalliance.openmobileapi.Session) sim_session);
} else{
Log.i(LOG_TAG, "Using MSC Session as its false");
msc_session = getMSCSession();
runOperation((com.mobilesecuritycard.openmobileapi.Session) msc_session);
}
I can even receive correct object class using
String classNameToBeLoaded = activeSession.getClass().getName();
But still not able to get object properties to activeSession object.
Is there any way to pass either of the session object to the runOperation method and only use activeSession for doing rest of the operation. As both objects has same methods and functionality but access different secure element on a android device. So, I do not want to write two different runOperation() method for the different objects. To be more precise, is it possible to cast an object type to another object. I am not sure about this. Any pointers or help will be grateful. I hope, I made my point clear what I want to achieve.
PS: please ignore syntax as I am just providing some code snippets to make my question clear.
You should be able to do this with reflection or even just instanceof, but why? Why not use overloading? Define two methods:
public void runOperation(com.mobilesecuritycard.openmobileapi.Session session) {
}
public void runOperation(org.simalliance.openmobileapi.Session session) {
}
If the goal is to reduce code duplication, then use a single method but have it take the least common ancestor superclass of the two types of sessions, which is hopefully not Object:
public void runOperation(SessionSuperclass session) {
// do something that can work with any type of session
doSomethingMoreSpecific(session);
}
And if necessary, implement two versions of doSomethingMoreSpecific(). That would be the object-oriented way of doing things, not instanceof or reflection.
if(activeSession instanceof com.mobilesecuritycard.openmobileapi.Session) {
// some stuff
} else if(activeSession instanceof org.simalliance.openmobileapi.Session) {
// some other stuff
}
You can do this check in your runOperation().
if(activeSession instanceof org.simalliance.openmobileapi.Session){
// Type 1
}
else if(activeSession instanceof com.mobilesecuritycard.openmobileapi.Session){
// Type 2
}
One solution that springs to mind is to have both of the objects implement a common interface.
For example
public interface ObjectIF
{
public void doSomething();
}
Have some classes that implement the interface:
public class ClassOne implements ObjectIF
{
public void doSomething() { // Code }
}
public class ClassTwo implements ObjectIF
{
public void doSomething() { // Code }
}
Now with your method you can do something like this:
public void doSomethingWithObject(ObjectIF object)
{
// Provided an object implements the interface, it can be passed here.
object.doSomething();
}
is it possible to cast an object type to another object?
Yes, you can cast.
You can check and cast:
if(activeSession instanceof org.simalliance.openmobileapi.Session){
org.simalliance.openmobileapi.Session mySession = (org.simalliance.openmobileapi.Session) activeSession
}
else if(activeSession instanceof com.mobilesecuritycard.openmobileapi.Session) {
com.mobilesecuritycard.openmobileapi.Session mySession = (com.mobilesecuritycard.openmobileapi.Session) activeSession
}

how to unit test a class which creates new objects

I'm using JUnit and Mockito to test some classes. The class itself creates an object from another class. A list called testList. Here my code:
public class A {
private List<B> bList;
//returns the bList
public List<B> getBList() {
return bList;
}
//checks the status by calling getStatus in class B
public Status getStatus() {
//status is an enum consists of PASSED and FAILED
Status finalStatus = Status.PASSED;
for (B be : this.getTestList()) {
if (be.getStatus() != Status.PASSED) {
finalStatus = Status.FAILED;
break;
}
}
return status;
}
}
public Class B {
private Status status = Status.FAILED;
public getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
}
What would be the best way to test the getStatus and getTestList methods in the class called Test.
Thank you very much....
I looked at your ClassA and I wondered how bList ever gets set to anything. Right now, there's no way for it to be anything other than null, which means that getStatus will throw a null pointer exception every time.
Your problem is that you are thinking about how to test methods instead of thinking about how to test behaviour. One reason why this is a problem is that your class has to fit in with the rest of your application in a certain way. To be sure that it does that, it needs certain behaviour, not certain details within each method. So the only meaningful test is one that checks the behaviour.
Perhaps more insidious is the fact that testing individual methods makes you focus on the code that you have in fact written. If you are looking at your code while you write your test, then your test becomes a self-fulfilling prophecy. You may have missed a whole set of behaviour that your class is required to provide; but if you only test the behaviour that your class does provide, you'll never know.
So, back to the problem in hand. I see four, maybe five behaviours that your class might be expected to fulfil. Maybe there are more - it's hard to tell if you only show us the code, and not the specification. You should write a test for each one. I strongly believe that the name of each test should describe the behaviour, rather than reflecting the name of the methods that the test uses. In this case, I might choose names like this.
public void statusIsPassedWhenEveryTestPassed()
public void statusIsFailedWhenEveryTestFailed()
public void statusIsFailedWhenSomeTestsPassedSomeFailed()
public void statusIsPassedWhenNoTests()
public void statusIsPassedWhenTestsNotSet() // this one currently fails
Within each test, I would create an object of ClassA, then do whatever has to be done to set the bList within the object. Lastly, I would call getStatus and assert that the return value is what I want. But the important point is that each test (except the last one) uses more than one method of ClassA, so these are not tests of an individual method.
You can provide setters (or constructor injection) for the objects in question as protected and then extend the class inside your test case to mock the objects or you can try using something like powermock. You would still need to provide a way to set those objects in question.
I guess it depends on how you can populate testList in a unit test. If you have, say, a setter, then you would not need any mocking frameworks
class TestTest {
Test test = new Test();
#Test void should_return_failed_if_a_single_test_failed() {
givenTestListWithOneFailedTest();
assertThat(test.getStatus(), is(Status.FAILED))
}
void givenTestListWithOneFailedTest() {
test.setTestList(createSomeTestListWithOnlyOneFailedTest());
}
#Test void should_return_passed_if_all_tests_passed() {
// ...
}
}

Java - Dynamic Class Casting from Interface to Implementation

I have read other related posts, but am still not quite sure how, or if it is possible to dynamically cast (interface to implementation) in Java. I am under the impression that I must use reflection to do so.
The particular project I am working on requires a usage of many instanceof checks, and it is — in my opinion — getting a bit out of hand, so would appreciate any ideas/solutions.
Below is a mini example I wrote up just to clarify exactly what I'm wanting to do. Let me know if you need more information:
Interface:
public interface IRobot {
String getName();
}
Implementations:
public class RoboCop implements IRobot {
String name = this.getClass()+this.getClass().getName();
public RoboCop() {}
public String getName() { return name; }
}
public class T1000 implements IRobot {
String name = this.getClass()+this.getClass().getName();
public T1000() {}
public String getName() { return name; }
}
The class that handles the implementations:
import java.util.LinkedList;
import java.util.List;
public class RobotFactory {
public static void main(String[] args) {
new RobotFactory();
}
public RobotFactory() {
List<IRobot> robots = new LinkedList<IRobot>();
robots.add( new RoboCop() );
robots.add( new T1000() );
System.out.println("Test 1 - Do not cast, and call deploy(robot)");
for(IRobot robot : robots) {
deploy(robot); // deploy(Object robot) will be called for each..
}
System.out.println("Test 2 - use instanceof");
for(IRobot robot : robots) { // use instanceof, works but can get messy
if(robot instanceof RoboCop) {
deploy((RoboCop)robot);
}
if(robot instanceof T1000) {
deploy((T1000)robot);
}
}
System.out.println("Test 3 - dynamically cast using reflection?");
for(IRobot robot : robots) {
//deploy((<Dynamic cast based on robot's type>)robot); // <-- How to do this?
}
}
public void deploy(RoboCop robot) {
System.out.println("A RoboCop has been received... preparing for deployment.");
// preparing for deployment
}
public void deploy(T1000 robot) {
System.out.println("A T1000 has been received... preparing for deployment.");
// preparing for deployment
}
public void deploy(Object robot) {
System.out.println("An unknown robot has been received... Deactivating Robot");
// deactivate
}
}
Output:
[RoboCop#42e816, T1000#9304b1]
Test 1 - Do not cast, and call deploy(robot)
An unknown robot has been received... Deactivating Robot
An unknown robot has been received... Deactivating Robot
Test 2 - use instanceof
A RoboCop has been received... preparing for deployment.
A T1000 has been received... preparing for deployment.
Test 3 - dynamically cast using reflection?
So, to sum up my question, how can I completely avoid having to use instanceof in this case. Thanks.
You can make deploy a method of IRobot, or use the visitor pattern.
And no, reflection will not make things any easier here.
Kent Beck says in his book Test Driven Development: Any time you're using run-time type-checking, polymorphism should help. Put the deploy() method in your interface and call it. You'll be able to treat all of your robots transparently.
Forget Reflection, you're just over thinking it. Remember your basic Object Oriented principles.
Dispatch of overloaded methods is done statically at compiletime, so your approach cannot be made to work. It's also very bad design. Doesn't it strike you as peculiar that the getName() method, the only thing that differs between the robot classes, is never actually called?
You have to ditch the overloaded methods, and instead use method overriding of methods in the robot classes, which you call directly. i.e.
public void deploy(IRobot robot) {
System.out.println("A "+robot.getName()+" has been received..."
+" preparing for deployment.");
// preparing for deployment
}
You can avoid instanceof by moving the deploy method in your IRobot interface and implementations.
The explanation of the behavior is that your three deploy methods are three different methods; overloaded methods with different signatures. At compile time, it's determined which one is chosen, not at runtime based on the real class...
Instead of using instanceof you can use the Factory Method Pattern
Definition of Factory method...
Like other creational patterns, it
deals with the problem of creating
objects (products) without specifying
the exact class of object that will be
created.
You will need a RobotCreatorFactory that will have a method called IRobot createRobot(String robotName) {...} (seeing that your robot returns a name. My suggestions is that each robot will have a public static String name NAME = Robocop.class.getName();. Inside the method you'll have a check such as
if (Robocop.NAME.equals(robotName) { return new RoboCop(); }
That way, you alleviate instanceof. And also, you can use #Meriton's advice on a DeploymentVisitor (using a visitor pattern)....
PS My example is a rough explanation of the Factory method pattern. An example exists in GoF book and Wikipedia.

Categories

Resources