Is A Mocking Library Redundant If I Already Have a Stub? - java

Let's say I have the following classes in the respective source folders/packages...
[src/myApp]
|_Employee «concrete»
|_Manager «abstract»
|_ManagerImpl «concrete» (Class Under Test)
|_Recruiter «abstract»
|_RecruiterImpl «concrete» (Collaborator)
...
public class ManagerImpl implements Manager {
...
private Recruiter recR;
...
public void growTeam( Object criteria ){
//...check preconditions
Employee newB = recR.srcEmployee( criteria );
//...whatever else
}
...
}
...
[test/myApp]
|_RecruiterStandIn «concrete»
|_ManagerImplTest
...
public class RecruiterStandIn implements Recruiter {
Map<Object, Employee> reSrcPool = new HashMap<>();
public RecruiterStandIn( ){
// populate reSrcPool with dummy test data...
}
public Employee srcEmployee( Object criteria ){
return reSrcPool.get( criteria );
}
}
...
public class ManagerImplTest {
...
// Class Under Test
private ManagerImpl mgr;
// Collaborator
private Recruiter recR = new RecruiterStandIn( );
...
public void testGrowTeam( ) {
//...
mgr.setRecruiter( recR );
mgr.growTeam( criteria );
// assertions follow...
}
...
}
...
Here are my questions: Given that I have a RecruiterStandIn concrete implementation that already exists within the codebase for testing purposes (in the test scope)...
Would it be redundant to also use a mock in the above unit test?
What would be the value (if any) in additionally doing something like this in the above unit test?
...
...
#Mock
private Recruiter recR;
...
...
public void testGrowTeam( ) {
...
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
...
You can safely assume that RecruiterStandIn does everything the class under test will ever require of it for the purposes of the above unit test. That is to say, for the sake of simple answers/explanations, there's no need to overcomplicate the above scenario with contrived what-ifs around maintenance of the stub and whatnot.
Thanks in advance.

My answers to your specific questions:
Would it be redundant to also use a mock in the above unit test?
As the unit test is written right now it would be redundant but my see answer to your second question below.
What would be the value (if any) in additionally doing something like this in the above unit test?
It think this is the way you should be doing your tests and I would recommend getting rid of your stub, RecruiterStandIn. Instead I would setup the recruit to return canned answers so you don't have to maintain two classes just to return some predefined data:
#Spy
private Recruiter recR;
public void testGrowTeam( ) {
// Setup canned data return
doReturn(generateTestEmployee()).when(recR).srcEmployee(any(Object.class));
expect( recR.srcEmployee( blah) ).andReturn( blah )...
// exercising/assertions/validations as usual...
}
FYI the above syntax would be for using Mockito. From what I can tell in your case Mockito gives you the power of stubbing out certain parts and much more without requiring you to create new test entities.
Original Answer
Definitely yes you should be doing mock object tests. Mocks Aren't Stubs. Mock object testing allows you to test the interactions between your classes and ensure that things are interacting with the world around them correctly. I think there is less value in these tests when you first write the classes and their corresponding tests. Mock object tests shine a year down the road when a new developer comes in and inadvertently your breaks code because she didn't understand that certain internal behavior was needed..
A somewhat contrived example would be if let's say we had a Car that needed to fill up some gas:
public class Car {
public void fuelUp()
}
Now with standard unit tests we would check that after calling fuelUp() the car was full of gas and that the proper amount of money was deducted from the driver. But since we never tested how fuelUp() was interacting with the world around it, it could easily be doing the following:
public void fueldUp() {
siphonGasFromNearestCar();
buyCoffeeAndChips()
}
But with mock object testing you can ensure that the Car is getting filled up in the proper and expected way.

Related

Testing Methods that create objects inside the method with Junit and Mockito

Hello I am fairly new to unit testing with Junit as well as Mockito. I think I have a fairly reasonable understanding of the principles but I can't seem to find any explanations of what I am specifically trying to test online.
I want to test a method, that calls several other methods (void and non-void), which also instantiates objects in the method body. I unfortunately cannot share the code as it is not mine, but here is a general format:
class classToTest {
private final field_1;
public void methodToTest( string id, List object_1, List object_2) {
try {
Map<SomeObject_1, SomeObject_2> sampleMap = new HashMap<>();
method_1(object_1, object_2); //void function modifies object_2
field_1.method_2(id, object_2);
Map<SomObeject_1, List<object>> groupedList = groupList(object_2)
//Then some stuff is added to the sampleMap
}
//catch would be here
}
At the moment I only care about testing method_1, and I cannot test directly as it is a private method so I must go through this parent method call. I wish I could change the code but I have been asked to keep it the same and to test in this manner with Mockito and Junit.
I know I need to Mock an object of the class to Test as well as its parameter:
private classToTest classToTestObject;
#Mock private field_1 f1;
#Before
public void setup() {
MockitoAnnotations.init.Mocks(this);
classToTestObject = mock(classToTest.class, CALLS_REAL_METHODS);
}
but I don't know where to start my actual test, as in how I can essentially just execute that one method call and ignore all the rest. I can't just not ignore the other objects and method calls either as the main method will throw exceptions if they are not handled correctly.
Any help and guidance is much appreciated, sorry that I could not share the code. Thank You!
At the moment I only care about testing method_1, and I cannot test directly as it is a private method so I must go through this parent method call.
Per your comment, and the note in your code:
method_1(object_1, object_2); //void function modifies object_2
You would set up a test that allows you to verify the expected final state of object_2. You would do this with a real instance of the class, not a mock.
#Test
public void method1Test() {
// Assemble - your preconditions
ClassToTest subject = new ClassToTest();
List<SomeType> object_1 = new ArrayList();
List<SomeOtherType> object_2 = new ArrayList();
// Populate object_1 and object_2 with data to use as input
// that won't throw exceptions. Call any methods on subject that put
// it in the desired state
// Act - call the method that calls the method under test
subject.methodToTest("some id that makes the method run correctly", object_1, object_2);
// Assert - one or more assertions against the expected final state of object_2
assertThat(object_2).matchesYourExpectations();
}

Unit testing when part of the class needs to be mocked

I have a class that I am trying to unit test. This class extends another class that I am not interested in unit testing at this time.
The following code is an over simplification of the code I am trying to test.
package com.example.somePackage;
public class ApiBase {
protected <T extends SomeClass> t getApi(Class<T> apiClass) {/* some logic*/}
}
package com.example.anotherPackage;
public MagicApiImpl extends ApiBase {
private final MagicApiHandler apiHandler = new MagicApiHandler();
public String doSomeStuff(String someString) {
final BookApi bookApi = getApi(BookApi.class);
// some logic
return apiHandler.someMethod(bookApi, someString);
}
}
I would like to test doSomeStuff() on MagicApiImpl The part I would like to mock is what comes back in getApi().
At first go I tried simply creating an Instance of MagicApiImpl and setting all the behind the scenes things that happen but that started to become over complex for the scenario I want to test and the number of times I need to test it in other classes. I will handle the testing of the logic in getApi() in a test of its own.
It would be helpful to use EasyMock to test this as it is what a majority of the tests for this project are written in but I would not be overly apposed to using mockito.
Edit
Okay I was reading about the Mockito.spy() That would have been wonderful but sadly getApi is protected and in another package. Worst case I could fall back on placing all the tests in that package but that makes it difficult track code.
Using Easymock partial mocks your test should look like this:
#Test
public void test() {
MagicApiImpl impl = EasyMock.createMockBuilder(MagicApiImpl.class)
.addMockedMethod("getApi")
.createMock();
EasyMock.expect(impl.getApi(BookApi.class)).andReturn(/**Wharever you need*/);
EasyMock.replay(impl);
String input = "INPUT";
String output = impl.doSomeStuff(input);
System.out.println("The OUTPUT is: " + output);
EasyMock.verify(impl);
//Run asserts here
}
Reference: http://easymock.org/user-guide.html#mocking-partial

Why and How to mock Model-Helperclasses?

I am reading a lot about unit testing, mocking, and all that stuff. I am currently also reading the book "Growing Object-Oriented Software Guided by Tests" by Steve Freeman and Nat Pryce.
I am starting to understand a lot of stuff but missing one crucial point, where I tried to find the answer anywhere online but am not satisfied yet.
In the following example I have an Online Shop, which receives messages from a third-party library, translates those, interpret them and eventually persist them into the database if needed. In a concrete case, I receive a message about a change of the address of a credit card of a user and want to store that information into a database.
The structure looks like this:
src/
domain/
MessageTranslator.java
ShopEventListener.java
ShopHandler.java
model/
CreditCard.java
CreditCardBase.java
CreditCardBuilder.java
User.java
UserBase.java
UserBuilder.java
test/
MessageTranslatorTest.java
ShopHandlerTest.java
MessageTranslatorTest
public class MessageTranslatorTest {
#Test
public void notifiesCCAddressChangedWhenChangeCCAddressMessageReceived() throws Exception {
ShopEventListener listenerMock = mock(ShopEventListener.class);
MessageTranslator messageTranslator = new MessageTranslator(listenerMock);
messageTranslator.processMessage("action=changeCCAddress; firstname=John; lastname=Doe; address=foobar3");
verify(listenerMock).ccAddressChanged("John", "Doe", "foobar3");
}
}
MessageTranslator (very simple for now)
public class MessageTranslator {
private final ShopEventListener listener;
public MessageTranslator(ShopEventListener userEventListener) {
listener = userEventListener;
}
public void processMessage(String message) throws Exception {
String[] attributes = message.split(";");
listener.ccAddressChanged(attributes[1].split("=")[1].trim(), attributes[2].split("=")[1].trim(), attributes[3].split("=")[1].trim());
}
}
ShopHandler
public class ShopHandler implements ShopEventListener {
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
// find a user (especially userid) in the Database for given firstname and lastname
UserBase userBase = new UserBase();
User user = userBase.find(aUser().withFirstname(firstname).withLastname(lastname).build());
if (user == null) {
throw new Exception();
}
// find the matching CreditCard for the userid in the database
Integer userid = user.getUserid();
CreditCardBase ccBase = new CreditCardBase();
CreditCard cc = ccBase.find(aCreditCard().withUserid(userid).build());
if (cc == null) {
throw new Exception();
}
// change address locally and then write it back to the database
cc.setAddress(newAddress);
cc.persist();
}
}
ShopHandlerTest
public class ShopHandlerTest {
#Test
public void changesCCAddressWhenChangeCCAddressEventReceived() throws Exception {
ShopHandler shop = new ShopHandler();
shop.ccAddressChanged("John", "Doe", "foobar3");
// TODO: How to test the changes in inner object?
}
}
This is where I always stumble.
Do I want to mock the helper classes UserBase and CreditCardBase to not perform any database queries but just return a prepared fake object?
Do I want to mock the persist-method to not write any real data to the database but maybe just test the parameters of the object to be persisted and have other (integration) tests test the database operations?
If 1. and 2. will be answered with yes, then what am I actually testing here? Is it worth unittesting this unit then?
Does the structure make sense this way?
If 1. and 2. will be answered with yes, then how do I mock the inner objects? I feel like dependency injection is the wront approach here, because first its no real dependency, but some helper classes, second (and more important imo) the ShopHandler class could be flooded with dependencies, as it might need alot of different helper classes and model classes to perform all the different actions. What if I just want to update the birthdate of a user based on an external message, do I still have to path all the dependencies like CreditCardBase and stuff?
Sorry for the long post, but it would be really awesome if you could push me in the right direction.
If you need more code for the above to understand, let me know.
Do I want to mock the helper classes UserBase and CreditCardBase to not perform any database queries but just return a prepared fake object?
Looks like your "helper classes" are actually repositories/DAOs. You normally want to test your business logic separately from DAOs, without the real database access. So yes, you should probably mock these DAOs and prepare the calls to them as they would work in reality. Prepared fake object is OK in most cases. You may also want to verify that your mocked DAO was actually called.
Do I want to mock the persist-method to not write any real data to the database but maybe just test the parameters of the object to be persisted and have other (integration) tests test the database operations?
I find it a bit strange that you seem to have the persist method in your business entity. Normally DAOs implement this type of methods.
Yes, if you test business logic you should mock the persist call to DAOs as well. If you don't do this, you'll be making tests of the business logic much heavier that they should be.
Yes, you should test your DAOs as well but separately from the business logic.
If 1. and 2. will be answered with yes, then what am I actually testing here? Is it worth unittesting this unit then?
You're testing you business logic. Just what is implemented in your ccAddressChanged method. Roughly:
if the user could not be found, an exception is thrown.
if user is found but users credit card could not be found, an exception is thrown.
if both could be found then credit card is persisted with an updated address.
Does the structure make sense this way?
It is not quite what I'm used to. You seem to have data access logic in entities, then you also have this "base" helper classess...
If 1. and 2. will be answered with yes, then how do I mock the inner objects?
With "inner objects" you probaby mean these helper classes. They are actually more that "helper classes", they are DAOs providing access to the database. You can pass or inject them from the outside. Basically this is dependency injection, your business logic depends on these DAO components. If you are able to pass them from the outside then in your test you can mock DAOs and pass mocks to your business service. With DI frameworks like Spring you'll have framework support for this.
Here'a a rough sketch of how a test for your ShopHandler class could look like with Spring and Mockito:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {ShopHandler.class})
public class ShopHandlerTest {
#Autowired
private ShopHandler sut;
#MockBean
private UserRepository userRepository;
#MockBean
private CreditCardRepository creditCardRepository;
#Test(expected = UserNotFoundException.class)
public void throwsUserNotFoundExceptionIfUserIsUnknown() {
when(userRepository.findUserByFirstNameAndLastName("Scott", "Tiger").thenReturn(null);
sut.ccAddressChanged("Scott", "Tiger", "Some Address");
}
#Test
public void successFullyUpdatesCreditCardAddress() {
when(userRepository.findUserByFirstNameAndLastName("Scott", "Tiger").thenReturn(new User("userId", ...));
when(creditCardRepository.findByUserId("userId")).thenReturn(new CreditCard(...));
ArgumentCaptor<CreditCard> creditCardCaptor = ArgumentCaptor.forClass(CreditCard.class);
verify(creditCardRepository).save(creditCardCaptor.capture());
sut.ccAddressChanged("Scott", "Tiger", "Some Address");
asserthThat(creditCardCaptor.getValue().getAddress()).isEqualTo("Some Address");
}
}
I feel like dependency injection is the wront approach here,
Dependency injection is a very sensible approach here.
because first its no real dependency,
Well, of course these are real dependencies.
but some helper classes,
Where do you think it end being a "helper class" and starts being a "real dependency"? What you call "helper classes" pretty much resemble DAOs which absolutely are "real dependencies".
second (and more important imo) the ShopHandler class could be flooded with dependencies, as it might need alot of different helper classes and model classes to perform all the different actions.
If you need to perform all these actions and need all these dependencies to do this, then this is the reality. The question is, however - do you really have to implement all of these actions in just one business service? Can't you divide this into many business services? You'll get smaller more focused classes then, and they will only need a few dependencies.
Since you're creating UserBase and CreditCard instances using new keyword in the method ccAddressChanged() - you cannot mock them!
In order to be able to mock them use DI - Dependency Injection (also called IoC - Inversion Of Control) by injecting instances of these class to ccAddressChanged():
change the signature of the class from:
public void ccAddressChanged(String firstname, String lastname, String newAddress)
to:
public void ccAddressChanged(String firstname, String lastname, String newAddress, UserBase userBase, CreditCard creditCard)
This way, you'll be able to mock them (using Mockito or any other mocking framework) and sending the mocks to the method.
Example of how the test will look, using Mockito:
#Test
public void changesCCAddressWhenChangeCCAddressEventReceived() throws Exception {
ShopHandler shop = new ShopHandler();
// mock UserBase and its behavior
UserBase mockedUserBase = mock(UserBase.class)
when(mockedUserBase.find(any()).thenReturns(mock(User.class));
// mock CreditCard
CreditCard mockedCreditCard = mock(CreditCard.class);
shop.ccAddressChanged("John", "Doe", "foobar3");
}
I feel like dependency injection is the wrong approach here, because
first its no real dependency, but some helper classes, second (and
more important imo) the ShopHandler class could be flooded with
dependencies
DI is not wrong:
It seems that ShopHandler class does have a real dependency on UserBase and CreditCardBase
To avoid "flooded" scenario you can inject them into the constructor of ShopHandler and save them into private fields. This way it's done only once during initialization and does not burden the user as well as doesn't expose implementation details.
Further, assuming that you refactored your code and now you're assigning UserBase and CreditCardBase in the constructor. I would refactor the code from:
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
// find a user (especially userid) in the Database for given firstname and lastname
UserBase userBase = new UserBase();
User user = userBase.find(aUser().withFirstname(firstname).withLastname(lastname).build());
if (user == null) {
throw new Exception();
}
// find the matching CreditCard for the userid in the database
Integer userid = user.getUserid();
CreditCardBase ccBase = new CreditCardBase();
CreditCard cc = ccBase.find(aCreditCard().withUserid(userid).build());
if (cc == null) {
throw new Exception();
}
// change address locally and then write it back to the database
cc.setAddress(newAddress);
cc.persist();
}
to:
#Override
public void ccAddressChanged(String firstname, String lastname, String newAddress) throws Exception {
User user = getUserByName(firstname, lastname);
CreditCard creditCard = getCCByUser(user);
setAddress(creditCard, newAddress);
}
and now you don't have to unit-test this ccAddressChanged() anymore. What you should do is test, and each one of the three methods: getUserByName, getCCByUser and setAddress. And each one of them is easy to mock and test!
Here is how I would write integration tests for ShopHandler (as shown in the question, with no changes):
public class ShopHandlerTest {
#Tested(fullyUnitialized = true) AppDB appDB;
#Tested ShopHandler sut;
#Test(expected = UserNotFoundException.class)
public void throwsUserNotFoundExceptionIfUserIsUnknown() {
sut.ccAddressChanged("Unknown", "user", "...");
}
#Test
public void successFullyUpdatesCreditCardAddress() {
User user = new User("Scott", "Tiger");
appDB.persist(user);
CreditCard cc = new CreditCard(user, ...);
appDB.persist(cc);
String newAddress = "New address";
sut.ccAddressChanged(user.getFirstName(), user.getLastName(), newAddress);
appDB.refresh(cc);
assertEquals(newAddress, cc.getAddress());
}
}
Above, #Tested is a JMockit annotation with full DI support, and also JPA/EJB/etc. support. It can be used as a meta-annotation, so you could create a #SUT or #TestUtil annotation to simplify its use in tests.
The fully-reusable test utility class AppDB would be something like this:
public final class AppDB {
#PersistenceContext private EntityManager em;
#PostConstruct
private void startTransaction() { ... using em... }
#PreDestroy
private void endTransaction() { ... rollback using em... }
public void persist(Object entity) { em.persist(entity); }
public void refresh(Object entity) { em.refresh(entity); }
}
Notice how nice and simple those integration tests look. They basically only contain high-level code, essentially the same kind of code you would see in the production (SUT) code. No complicated mocking APIs to get you in trouble. They are also fast and stable.

What is the difference between a Seam and a Mock?

Its being a few months since I am working with java legacy code, this are some of the things I am dealing with:
0% test coverage.
Huge functions in occasions I even saw some with more than 300 lines of code.
Lots of private methods and in occasions static methods.
Highly tight coupled code.
At the beginning I was very confused, I found difficult to use TDD in the legacy. After doing katas for weeks and practicing my unit testing and mocking skills, my fear has decreased and I feel a bit more confident. Recently I discovered a book called: working effectivelly with legacy, I didn't read it, I just had a look at the table of contents and I discovered something that is new for me, The Seams. Apparently this is very important when working in the legacy.
I think that this Seams could help me alot in breaking dependencies and make my code testeable so I can increase the code coverage and make my unit testing more precise.
But I have a lot of doubts:
Can somebody explain me the difference between a seam and a mock?
Do Seams, break TDD rules in what regards not touching production code, before is tested?
Could you show me some simple example that compares a Seam and a Mock?
Below I would like to paste an example I did today where I tried to break a dependency with the goal of making the code testeable and finally increasing test coverage. I would appreciate if you could comment a bit if you see some mistakes?
This is how the legacy code looked like at the beginning:
public class ABitOfLegacy
{
private String sampleTitle;
String output;
public void doSomeProcessing(HttpServletRequest request) {
String [] values = request.getParameterValues(sampleTitle);
if (values != null && values.length > 0)
{
output = sampleTitle + new Date().toString() + values[0];
}
}
}
If I just add a unit test that calls that method and asserts that variable output, has a certain value after the call,then I would be making a mistake, because I am not unit testing, I would be doing integration testing. So what I need to do, Is get rid of the dependency I have in the parameter. To do So, I replace the parameter with an interface:
public class ABitOfLegacy
{
private String sampleTitle;
String output;
public void doSomeProcessing(ParameterSource request) {
String [] values = request.getParameters(sampleTitle);
if (values != null && values.length > 0)
{
output = sampleTitle + new Date().toString() + values[0];
}
}
}
This is how the interface looks like:
public interface ParameterSource {
String[] getParameters(String name);
}
The next thing I do, is create my own implementation of that interface but I include the HttpServletRequest as a global variable and I implement the method of the interface using the method/s of HttpServletRequest:
public class HttpServletRequestParameterSource implements ParameterSource {
private HttpServletRequest request;
public HttpServletRequestParameterSource(HttpServletRequest request) {
this.request = request;
}
public String[] getParameters(String name) {
return request.getParameterValues(name);
}
}
Until this point, I think that all the modifications on the production code were safe.
Now I create the Seam in my test package. If I understood well, now I am able to safely change the behavoir of the Seam. This is how I do it:
public class FakeParameterSource implements ParameterSource {
public String[] values = {"ParamA","ParamB","ParamC"};
public String[] getParameters(String name) {
return values;
}
}
And the final step, would be to get support from the Seam, to test the original behavoir of the method.
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import code.ABitOfLegacyRefactored;
import static org.hamcrest.Matchers.*;
public class ABitOfLegacySpecification {
private ABitOfLegacy aBitOfLegacy;
private String EMPTY = null;
#Before
public void initialize() {
aBitOfLegacy = new ABitOfLegacy();
}
#Test
public void
the_output_gets_populated_when_the_request_is_not_empty
() {
FakeParameterSource fakeParameterSource = new FakeParameterSource();
aBitOfLegacy.doSomeProcessing(fakeParameterSource);
assertThat(aBitOfLegacy.output,not(EMPTY));
}
#Test(expected=NullPointerException.class)
public void
should_throw_an_exception_if_the_request_is_null
() {
aBitOfLegacy.doSomeProcessing(null);
}
}
This will give me 100% test coverage.
I appreciate your thoughts:
Did I break the dependency correctly?
Are the unit tests missing something?
What could be done better?
Is this example good enough to help me understand the difference between a Seam and a Mock?
How could a mock help me here if I don't use the Seam?
A seam is a place in the code that you can insert a modification in behavior. You created a seam when you setup injection of your dependency.
One way to take advantage of a seam is to insert some sort of fake. Fake's can be hand-rolled, as in your example, or be created with a tool, like Mockito.
So, a mock is a type of fake, and a fake is often used by taking advantage of a Seam.
As for your tests and the way you broke the dependency, that's pretty much how I would have done it.
Seams
A seam is a place that allows you to modify the behavior without modifying the code.
In your example, the following is an example of an Object seam (if i'm not mistaken). It allows you to pass in a different object without having to change the code. hence it is a type of seam.
public void doSomeProcessing(ParameterSource request) {..}
By making the parameter an abstract type (instead of a concrete class), you have introduced a seam. The seam now allows you to modify the behavior of the method without editing its code - i.e. at the place of invokation, I can pass in a different object and make the method do something else.
Mocks
Now instead of creating your custom fake (creating a subtype of the interface), you could using a Mock framework to do something like this
Mocks also support asserting whether specific methods were called on it, argument matching and other nifty functionality to be consumed by tests. Less test code to maintain. Mocks are primarily used to assert that a specific call is being made to a dependency. In your example, you seem to be in need of a Stub, you just want to return a canned value.
Pardon my rusty JMock..
#Test
public void
the_output_does_not_get_populated_when_the_request_is_empty
() {
Mockery context = new Mockery();
final ParameterSource mockSource = context.mock(ParameterSource.class)
context.checking(new Expectations(){{
oneOf(mockSource).getParameters();
will(returnValue(new string[]{"ParamA","ParamB","ParamC"} );
}});
aBitOfLegacy.populate(mockSource);
assertThat(aBitOfLegacy.output,not(EMPTY));
}
in .Net
var mockSource = new Mock<ParameterSource>();
mockSource.Setup(src => src.GetParameters())
.Returns(new []{"ParamA","ParamB","ParamC"});

junit test class for the following code

How to mock the object for the Phone object.
code bellow,
public class Fortest {
UserDao userdao = new UserDao();
Phone name = new Phone();
public String handleUser(User user) {
String returncode="failed";
//User usr = new User("bob");
String username=user.getUsername();
String pass=user.getPass();
System.out.println("username and password : "+username+" : "+pass);
Phone name = new Phone();
String ph = name.getA();
System.out.println("ph "+ph);
if(ph.equalsIgnoreCase("test")){
System.out.println("A "+ph);
returncode="done";
}
System.out.println("returning "+returncode);
return returncode;
//System.out.println("name "+name.toString());
//System.out.println(name.getA());
}
}
Thanks
First I'm going to make some assumptions.
user.getUsername() & user.getPass() have no side affects.
The System.out.println are not important to you.
Thus done your class becomes:
public class Fortest {
Phone name = new Phone();
public String handleUser(User user) {
String ph = name.getA();
if(ph.equalsIgnoreCase("test")){
return "done";
}
return "failed";
}
}
So your test has two conditions. Either phone.getA() is "test" and you return "done" or it is not and you return "failed".
So how to set set "getA". One thing is for sure, we will need to be able set "name" from the test. For that we need to "inject" it (we can do it a number of other ways, but I loves injection). I'd use Guice, many would use Spring. Some would use one of the other injection frameworks. But in the tests most of us would use manual injection.
public class Fortest {
Phone name;
Fortest(Phone name) {
this.name = name;
}
public String handleUser(User user) {
String ph = name.getA();
if(ph.equalsIgnoreCase("test")){
return "done";
}
return "failed";
}
}
public class TestFortest {
#Before
public void before() {
name = ; //...
subject = new Fortest(name);
}
}
Now the tests are fairly simply:
public void whenTestModeIsEnabledThenReturnDone() {
setPhoneIntoTestMode();
String actual = subject.handleUser(null);
assertEquals(actual, "done");
}
public void whenTestModeIsDisabledThenReturnFailed() {
setPhoneIntoLiveMode();
String actual = subject.handleUser(null);
assertEquals(actual, "failed");
}
The implementation of setPhoneIntoTestMode/setPhoneIntoLiveMode will depend on how complex Phone is. If it is complex than we would look at "facking" it in some way (mocks, stubs, etc). This could be a chunk of code you write, it could be using a tool like Mocketo.
If the Phone object is simple, and has or can have a "setA" method, then just use that.
I'm sure later you will need userdao. The same thing will be done at that point. Inject and mock/setup the object.
You don't. One of the rules of mocking is: you never mock entities or value objects. If you need to break this rule, it means that you probably have a design flaw.
If you need to mock a new, you'll need to pass a factory to the object, and then you mock the factory. A very common example of this is when you need to mock Date objects, which is very well explained in this other question: How to mock the default constructor of the Date class (check the first answer).
As a side note, calling an instance of Phone name...mmm that doesn't look right.
Class mocking is very easy using EasyMock. It makes use of cglib internally to perform class mocking. EasyMock can both mock interfaces and classes (class mocking). See documentation.
So, to get your Phone mock, just call createMock(Phone.class):
Phone phoneMock = createMock(Phone.class);
As Augusto stated, it is not really good design to make use of class mocking though. A better way would be to program towards interfaces and use a dependency injection framework.
So you need to do one of the following options to inject mocks into the fields name and userdao (I am going to assume that you can use the new Phone field instance instead of the one created in the method.
Do not call constructors in your code directly but instead use field injection via setters. This will allow your test to provided mocked instances of the two classes. If you must create a new instance in the method then consider using a factory which can be mocked.
Provide default scope setter methods for the two fields. These methods would be in place for test purposes only.
Use Refection to set the fields to mocked instances. An easy way to do this is with Spring's ReflectionTestUtils.
Once one of these is in place you can provide mocked instances (maybe using Mockito) to drive the behavior you wish to test. I would suggest that option 1 is the best if fesible, then option 3. However, the disadvantage to options 3 is that the test is dependant of the names of private fields.
Then...
Phone phone = Mockito.mock(Phone.class);
Mockito.when(phone.getA()).thenReturn("blah");
objectUnderTest.setPhone(phone);
objectUnderTest.handleUser(...);

Categories