I'm working with some legacy code and I need to test that some expensive service is called (it makes network calls, send emails, etc.).
I'm able to inject a fake service instead of the original one by means of the framework in use (jboss seam 2). See this question: Mock #org.jboss.seam.annotations.in behaviour for unittest
I now want my fake object to be a smarter mock to assert if it has been called or not, etc. I would like it to be a Mockito or Easymock or some other thing mock. But constructing the mock the classical way in the test and then injecting it, is not working because of the way seam 2 and seam test deals with injection. See the link above.
Question: is there a way to have my mock extend or be annotated in order to become a Mockito or something mock? How can I get a reference to it in my tests?
I disagree with the answer of the question you linked to. A unit test should test the class independantly from the environment it's supposed to work in. And dependency injection frameworks are precisely used to be able to inject mock dependencies in unit tests, without needing any complex environment to run the unit test.
I don't know Seam, but its documentation says that #In can be placed on a property accessor. I would just have the class under test like this:
public class someBean implements Serializable {
private ApplicationBean applicationBean
#In
protected void setApplicationBean(ApplicationBean applicationBean) {
this.applicationBean = applicationBean;
}
...
}
And I would just call the setter to inject the mock in the unit test.
You could also let the code as is, but provide a setter or an additional constructor to be able to inject a mock applicationBean.
You need a class with the same name but a higher precedence. I've built plenty of mocks just doing that.
You give the same #name to your mock class and you define #install(precedence=MOCK). As soon as this class is in the classpath it will be used instead of your normal class (precedence default is application if I remember correctly).
I have no code ready here just now but I mock the facesmessage for example so during testing I can read these messages from this class and validate them.
Related
I want to write a generic test class for special kind of integration test. The generic class has to setup a server before all test in a subclass and tear down after all tests. Each subclass has to provide one string parameter to setup the server.
My problem is to find a good design for it. Since #Before/AfterClass are static the given parameter must be static to. Setting the parameter in constructor of subclass is too late.
I also thought about creating a custom test runner and a custom annotation to set the parameter - but that's probably too much for now?!
Edit:
Because of kind of setup it is essential that setup and tear down is only called once per test class - not for every test.
My Stack is Camel + Guice (Standalone app)
Sounds like you want to use a Rule, in particular perhaps the ExternalResources ones.
By using a ClassRule and runner you should be able to instantiate normal objects and avoid the static methods, but have sub-classes instantiate their own / customised rules to set up your server as required.
I'm currently working with mocking with Mockito using jUnit and I've stumbled upon the Partial Mocking section where you use Mockito.spy to partially mock the object. I don't seem to understand this concept of partial mocking since I can't find a scenario why I should use it (since it's pretty similar to mocking in general).
Can anybody explain how partial mocking differs from the normal mocking? And if possible, kindly provide examples.
Thanks!
Partial mocking is where you take a class and ask it to behave as normal, except you want to override certain functionality.
This is useful for unit testing services who communicate with other parts of your application. By overriding the behaviour that would call the other part of your application you can test your service in isolation.
Another example would be when a component would communicate with a database driver. By mocking the part that would communicate with the driver, you can test that part of the application without having to have a database.
From the EasyMock 2.2 classextension documentation:
Sometimes you may need to mock only some methods of a class and keep
the normal behavior of others. This usually happens when you want to
test a method that calls some others in the same class. So you want to
keep the normal behavior of the tested method and mock the others.
I sometimes use this to mock (complicated or process intensive) private methods that are allready fully tested.
Partial mocking can be very handy, but I try to avoid it as much as possible.
Partial mocking:
Say you have a class which takes 10+ parameters for a constructor (this shouldn't ever happen but for this example lets say it does) it's a real chore to create that entire object. Frameworks like mockito let you just use the parts of the object you really want to test.
for example
#Mock BigClass big; //contains loads of attributes
...
when(big.getAttributeOneOfTwenty()).thenReturn(2); //these are static imports from mockito
I find it useful when I'm forced to work with APIs relying on inheritance from abstract classes and/or legacy code working with nonmockable static classes (one real life example - DAO).
Partial mocking (in sense of using the Spy facility from Mockito) allows you to mock calls to inherited methods in the first case, or wrap calls to static methods you are forced to use into normal methods that you can mock, verify etc.
Generally you should design and write code in such a way, that you won't need this (dependency injection, single responsibility per class etc). But from time to time it's useful.
A quick and rough example, to visualize the static API example:
class BigUglyStaticLegacyApi {
public static Foo someStaticMethodFetchingFoo() {...}
}
class Bar {
public void someMethodYouTest() {
Foo foo = getFoo();
//do something with Foo (a FooBar, for example :) )
}
/*this one you mock via spying - not the most elegant solution,
but it's better than nothing */
#VisibleForTesting
protected Foo getFoo() {
return BigUglyStaticLegacyApi.someStaticMethodFetchingFoo();
}
}
I use it the most to mock some methods in my CUT (Class Under Test) but not the method/s I'm actually unit testing. It is an important feature that should be used in unit testing with Mockito.
I'm working with the Struts2 framework and would like to unit test the execute method below:
public String execute() {
setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));
setUserPrincipal(); //fetches attribute from request and stores it in a var
setGroupValue(); //
setResults(getMyDao().getReportResults(getActionValue(), getTabName());
setFirstResultSet((List) getResults()[0]);
setSecondResultSet((List) getResults()[1]);
return SUCCESS;
}
As you can see most of the logic is database related. So how would I go about unit testing this functionality? I would like to unit test by mocking a HTTPServletRequest with few request variables inside it.
My questions are:
How can I fake/mock a request variable as if its coming from a browser
Should my unit test be calling the actual DAO and making sure that the data is coming back?
If so, how can I call the DAO from unit test since the DAO is tied to the server since jndi pool settings reside on the application server.
I'd appreciate any book/article that shows how to really accomplish this.
The code you have shown us is not enough to fully answer your question.
Line by line
setDao((MyDAO) ApplicationInitializer.getApplicationContext().getBean("MyDAO"));
This is the hardest line since it uses static method. We would need to see how ApplicationInitializer works. In ideal world the getApplicationContext() method should return mock of ApplicationContext. This mock in turns should return MyDAO when getBean("MyDAO"). mockito is perfectly capable of handling this, as well as all other mocking frameworks.
setUserPrincipal(); //fetches attribute from request and stores it in a var
Where does the request come from? Is it injected to action class? If so, simply inject mocked request object, e.g. MockHttpServletRequest.
setGroupValue(); //
Same as above? Please provide more details, what this method actually does?
setResults(getMyDao().getReportResults(getActionValue(), getTabName());
Your previously created mock should return something when getReportResults() is called with given arguments.
setFirstResultSet((List) getResults()[0]);
setSecondResultSet((List) getResults()[1]);
I guess methods below set some field on the action class. Because you have full control over what was returned from mocked getReportResults(), this is not a problem.
return SUCCESS;
You can assert whether SUCCESS was the result of execution.
Now in general
How can I fake/mock a request variable as if its coming from a browser
See above, there is a mock built-in in Spring.
Should my unit test be calling the actual DAO and making sure that the data is coming back?
If your unit test calls real DAO, it is no longer unit test. It is an integration test.
If so, how can I call the DAO from unit test since the DAO is tied to the server since jndi pool settings reside on the application server.
This means you are doing integration testing. In that case you should use in-memory database like h2 so you can still run the test on ci server. You must somehow configure your application to fetch DataSource from different place.
Final note
In essence you should inject mocks of everything to your Struts action class. You can tell mocks to return any value upon calling. Then, after calling execute(), you can verify given methods were called, fields set and result value is correct. Consider splitting this to several tests.
Code review
Struts 2 integrates perfectly with Spring. If you take advantage of that functionality Spring container will automatically inject MyDAO to your action class. The first line becomes obsolete.
This code is hard to unit test because instead of using Spring as intended (i.e. as a dependency injection framework), you use it as a factory. Dependency injection is precisely used to avoid this kind of bean lookup you're doing, which is hard to test. The DAO should be injected into your object. That way, you could inject a mock DAO when unit testing your object.
Also, this logic is not database-related at all. The DAO contains the database-related logic. This action uses the DAO, and the DAO is thus another unit (which should be tested in its own unit test). You should thus inject a mock DAO to unit test this method.
Finally, this method doesn't use HttpServletRequest (at least not directly), so I don't understand why you would need to use a fake request. You could mock the setXxx methods which use the request.
Instead of simply mocking the HTTPServletRequest, how about
mocking an actual automated targeted request to the application
itself? Check out Selenium which lets you do just that.
For testing DAOs (integration testing), you could create your databases in memory using HSQLDB, which will allow you to create / delete objects from your tests, and making sure they are persisted / retrieved properly. The advantage with HSQLDB is that your tests will run much quicker than they will with an actual database. When the time comes to commit your code, you could run the tests against your actual database. Usually, you would setup different run configurations in your IDE to facilitate this.
The easiest way to make your injected daos available to your tests is to let your unit test classes extend AbstractJUnit4SpringContextTests. You could then use the #ContextConfiguration annotation to point to multiple xml application context files, or if you use annotation based configuration, point it to your context file which has the <context:annotation-config /> declaration in it.
In following code the issue is, that I cannot test dao.add() without using dao.list().size() and vice versa.
Is this approach normal or incorrect? If incorrect, how can it be improved?
public class ItemDaoTest {
// dao to test
#Autowired private ItemDao dao;
#Test
public void testAdd() {
// issue -> testing ADD but using LIST
int oldSize = dao.list().size();
dao.add(new Item("stuff"));
assertTrue (oldSize < dao.list().size());
}
#Test
public void testFind() {
// issue -> testing FIND but using ADD
Item item = new Item("stuff")
dao.add(item);
assertEquals(item, dao.find(item.getId()));
}
}
I think your test are valid integration tests as stated above, but I would use Add to aid in the testing of of Find and vice verse..
At some level you have to allow yourself to place trust in your lowest level of integration to your external dependency. I realize there is a dependency to other methods in your tests, but I find that Add and Find methods are "low level" methods that are very easy to verify.
They essentially test each other as they are basically inverse methods.
Add can easily build preconditions for find
Find can verify that an add was successful.
I can't think of a scenario where a failure in either wouldn't be caught by your test
Your testAdd method has a problem: it depends on the assumption that ItemDao.list functions properly, and yet ItemDao is the Class that you're testing. Unit tests are meant to be independent, so a better approach is use plain JDBC -as #Amir said- to verify if the record was introduced in the database.
If you're using Spring, you can relay on AbstractTransactionalDataSourceSpringContextTests to access JDBCTemplate facilities and assure a rollback after the test was executed.
I use direct JDBC (using Spring's JdbcTemplate) to test the DAO methods. I mean I call the DAO methods (which are Hibernate base), and then confirm them using JDBC direct SQL calls.
The smallest unit under test for class-based unit testing is a class.
To see why, consider that you could, in theory, test each method of the class in isolation from all other methods by bypassing, stubbing or mocking them. Some tools may not support that; this is theory not practice, assume they do.
Even so, doing things that way would be a bad idea. The specification of an individual function by itself will vary between vaguely meaningless and verbosely incomprehensible. Only in the pattern of interaction between different functions will there exist a specification simpler than the code that you can profitably use to test it.
If you add an item and the number of items reported increases, things are working. If there is some way things could not be working, but nevertheless all the patterns of interaction hold, then you are missing some needed test.
I have a bean in my applicationContext-test.xml that I use for mocking an external search engine. This way, when I run tests, any time my application code refers to this search engine, I know that I am using my mock engine instead of the real one.
A problem I am facing is that I want this engine to behave differently in different scenarios. For example, when I call getDocuments(), I usually want it to return documents. But sometimes I want it to throw an exception to make sure that my application code is handling the exception appropriately.
I can achieve this by referencing the bean in my test code and changing some stubs, but then I have to change the stubs back to what they were so that my other tests will also pass. This seems like bad practice for many reasons, so I'm seeking alternatives.
One alternative I considered was to reinitialize the bean completely. The bean is initialized from the applicationContext-test.xml with a static factory method. What I want to do is:
Reference the bean from my test code to change some of its stubs
Run the test using these new stubs
At the end of this test, reinitialize the bean using the static factory method specified in applicationContext-test.xml
I tried something like this:
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] { "applicationContext-test.xml" });
Factory factory = appContext.getBean(Factory.class);
factory = EngineMocks.createMockEngineFactory();
But this does not do the trick. Any tests that are run after this will still fail. It seems that my new factory variable contains the Factory that I want and behaves accordingly, but when the bean is referenced elsewhere, getDocuments() still throws the exception that was stubbed in previously. Clearly, my re-initialization only affected the local variable and not the bean itself.
Can someone tell me how I can accomplish my goal?
Update
While I appreciate suggestions as to how to write better tests and better mocks, my goal is to reinitialize a bean. I believe there is value in learning how to do this whether it fits my use case or not (I believe it does fit my use case, but I'm having a hard time convincing some of my critics here).
The only answers that will get any up votes or green ticks from me are those which suggest how I can reinitialize my bean.
You should define the cases when you want a result and the cases when you want an exception. They should be differentiated by input parameters to the method. Otherwise it is not a good test. So, for a given set of parameters the output should be predictable.
How about injecting different implementations of the search engine? Just create more beans representing the different mocks of the search engine.
one test class is initialized with one mock and another test class with another mock; this, of course, means you'll have more test classes for a certain class that you are testing (not that good/clean)
or...
inject more mocks (of the search engine) in 1 testing class. some testing methods (from that testing class) use one mock, other testing methods use another mock
Instead of:
factory = EngineMocks.createMockEngineFactory();
do:
factory.callMethodThatChangesTheStateOfThisObjectSuchThatItIsSuitableForYourTest(withOptionalParameters);
Also, if you are using Spring Integration Testing, make sure to annotate your method with #DirtiesContext so it won't affect the next test.