Let's assume that i have a Dao class with a method that establishes connection and reads int from database.
public class Dao {
public static final Dao INSTANCE = new Dao();
public int getSomething() {
//connection
return 1;
}
}
And i have a Servlet with such code inside.
int i = Dao.INSTANCE.getSomething();
The problem is that i don't know how to mock this Dao.INSTANCE call...
If it was for example a servlet with session. I could make it like this.
Session s = EasyMock.createMock(Session.class);
expect(request.getSession()).andReturn(s);
but i am not able to make it like this
Dao dao = EasyMock.createMock(Dao.class);
expect(Dao.INSTANCE).andReturn(dao);
Make the dao an instance variable, and then you can easily mock it:
public class MyServlet extends HttpServlet {
Dao dao = Dao.INSTANCE;
}
MyServlet servlet = new MyServlet();
servlet.dao = EasyMock.createMock(Dao.class);
I'd recommend you change the code so calling a method will return a singleton. Such as
public class Dao {
public static Dao singleton;
public static Dao getInstance(){
if(singleton == null){
singleton = new Dao();
}
return singleton;
}
public int getSomething() {
//connection
return 1;
}
}
And after that mock getInstance using PowerMock.
Take a look here for how.
Related
I have a class below for which I want to write a unit test
abstract class ProductImpl{
#Inject DataServices ds; // using Guice
public Response parse(String key, Long value){
Response res = ds.getResponseObject(); // Response object is created using DataServices object
res.id = key;
res.code = value;
}
}
And I have a test as below
class ProductImplTest{
#InjectMocks ProductImpl impl;
Map<String, Long> map;
#Before
map.put("abc", 10L);
map.put("xyz", 11L);
}
#Test
public void test(){
for(String key: map.keySet()){
Response res = impl.parse(key, map.get(key));
// and check if fields of Response object are set correctly i.e res.id is abc and value is 10L
}
}
But when i debug the test and control goes to parse method , DataServices object ds is null. How to instantiate this object through test . I do not want to use mocking, I want real response objects to be created and test the values set in them.
You can use Mockito
#RunWith(MockitoJUnitRunner.class)
class ProductImplTest {
#Mock DataService dService;
#InjectMocks ProductImpl sut;
#Test
public void test() {
ResponseObject ro = new ResponseObject();
String string = "string";
Long longVal = Long.valueOf(123);
sut.parse("string", longVal);
verify(dService).getResponseObject();
assertThat(ro.getId()).isEqualTo("string");
// you should use setters (ie setId()), then you can mock the ResponseObject and use
// verify(ro).setId("string");
}
}
EDIT:
With ResponseObject being an abstract class or preferably an interface, you'd have
interface ResponseObject {
void setId(String id);
String getId();
// same for code
}
and in your test
#Test public void test() {
ResponseObject ro = mock(ResponseObject.class);
// ... same as above, but
verify(dService).getResponseObject();
verify(ro).setId("string"); // no need to test getId for a mock
}
Try with constructor injection:
class ProductImpl{
DataServices ds;
#Inject
public ProductImpl(DataServices ds) {
this.ds = ds;
}
}
I have a simple Controller class like below:-
#RestController
public class CrawlerAppController {
private static final Logger LOGGER = LoggerFactory.getLogger(CrawlerAppController.class);
#Autowired
private CrawlerServiceInterface crawlerService;
/* The response time of the crawling operation is directly proportional to the no of pages
* we want to crawl. Keeping a default value of 10 so we can view the results quicker.
* author: Arunava Paul
*/
#RequestMapping(value = "/crawl", method = { RequestMethod.GET })
public Object crawlUrl(#RequestParam(value = "URL") String URL,
#RequestParam(value = "max", defaultValue = "10") int maxPages) throws Exception {
if(!URL.startsWith("https://"))
URL="https://"+URL;
LOGGER.info("Request Received. Domain "+URL+" Pages to be Crawled "+maxPages);
return crawlerService.crawlService(URL, maxPages);
}
}
I have written a Junit class like below:-
#RunWith(PowerMockRunner.class)
public class CrawlerAppControllerTest {
Object obj=new Object();
#Spy
#InjectMocks
private CrawlerServiceInterface crawlerService = Mockito.any(CrawlerService.class);
#InjectMocks
CrawlerAppController appController = new CrawlerAppController();
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testController() throws Exception {
when(crawlerService.crawlService("https://vogella.com", 20)).thenReturn(obj);
assertEquals(appController.crawlUrl("vogella.com",20), obj);
}
}
It's always going into the Service class and the when statement is not running.
Can someone please advise what have I done wrong. Below error comes if I run Junit.
You should declare crawlerService like this:
#Mock
private CrawlerServiceInterface crawlerService;
The declaration of crawlerService in the test class should be:
#Mock
private CrawlerServiceInterface crawlerService;
I've a spring boot project working on mysql DB. To encrypt some column I used the mysql function aes_encrypt, aes_decrypt and I stored my secret_key in a property file. Now to make some query on db I've to use in the crudrepository some native query like this.
#Query(value = "select * from a_table at where AES_DECRYPT(at.column1, +StaticClass.KEY+)= 'ABC'", nativeQuery = true)
public List<A>findByParameter();
I get this error "The value for annotation attribute Query.value must be a constant expression"
But the property KEY is already a FINAL property instantiate in this way
public class StaticClass {
static {
Properties prop = new Properties();
InputStream input;
try {
input = new FileInputStream("application.properties");
prop.load(input);
} catch (IOException e) {
logger.error("Error");
}
if(prop.getProperty("property1")==null) {
logger.error("property not found");
}
KEY=prop.getProperty("property1", "");
}
public static final String KEY;
One solution is to store the key in the code, but i need to keep the key in a property file. How can solve this problem?
Updated 1
I tried also in this way
public class StaticClass {
#Value(value="property1")
public static final String KEY;
}
You can create for this constants like below.
public enum Foo {
FOO("app.foo"), FOO_BAR("app.foo.bar");
private Environment environment;
private final String propertyKey;
Foo(String propertyKey) {
this.propertyKey = propertyKey;
}
public String getValue() {
return environment.getProperty(propertyKey);
}
private void setEnvironment(Environment environment) {
this.environment = environment;
}
#Component
private static class EnvironmentInjector {
#Autowired
private Environment environment;
#PostConstruct
private void postConstruct() {
for (Foo fT : EnumSet.allOf(Foo.class))
fT.setEnvironment(environment);
}
}
}
then you can use like this :
Foo.FOO.getValue()
#Query(value = "select * from a_table at where AES_DECRYPT(at.column1, +Foo.FOO.getValue()+)= 'ABC'", nativeQuery = true)
public List<A>findByParameter();
Maybe the title is not the best to explain the problem, but I'll try to explain it as best as possible.
I have an Spring Boot Application using JPA and MySQL, so in order to check everything worked properly, I made a simple CRUD test for my database, and I found problems with autowiring which are explained in my previous question. The solution for those problems was just adding the #ComponentScan annotation to my Application.java.
It was the solution for the test because it run without problems, but then I find another problem. Apart from the test, I need my application to show a list of Proposals made by some Users and also some Comments. Before adding that annotation, the HTMLs showed the correct information, but after adding it shows information about the database in JSON format on the main page and if I try to navigate to "localhost:8080/viewProposal" p.e. it shows a WhiteLabel error page with error code 404. I have no idea why it is replacing the HTMLs because I have just one controller and is not a RESTController. These are my classes:
Application.java
#SpringBootApplication
#EntityScan("persistence.model")
#EnableJpaRepositories("persistence.repositories")
#ComponentScan("services.impl")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
MainController.java
#Controller
#RequestMapping("/")
public class MainController {
private static final Logger logger = Logger.getLogger(MainController.class);
private List<SseEmitter> sseEmitters = Collections.synchronizedList(new ArrayList<>());
private Map<String, Proposal> proposals = generateProposals();
#RequestMapping({"/live","/"})
public String landing(Model model) {
return "index";
}
#RequestMapping("/viewProposal")
public String viewProposal(Model model, Long id) {
//put the object in the map
return "viewProposal";
}
#KafkaListener(topics = "newVote")
public void listen(String data) {
String[] contents = data.split(";");
if(contents.length!=2)
return;
Proposal p;
int newVote;
if (proposals.containsKey(contents[0]))
p = proposals.get(contents[0]);
else {
p = new Proposal();
p.setTitle(contents[0]);
proposals.put(p.getTitle(), p);
}
if (contents[1].equals("+"))
newVote = +1;
else if (contents[1].equals("-"))
newVote = -1;
else
newVote = 0;
p.setNumberOfVotes(p.getNumberOfVotes() + newVote);
logger.info("New message received: \"" + data + "\"");
}
private static Map<String, Proposal> generateProposals() {
Map<String, Proposal> lista = new HashMap<String, Proposal>();
Proposal p = new Proposal();
p.setTitle("tituloPrueba");
lista.put("tituloPrueba", p);
return lista;
}
#ModelAttribute("proposals")
public Map<String, Proposal> getProposals() {
return proposals;
}
public void setProposals(Map<String, Proposal> proposals) {
this.proposals = proposals;
}
}
MvcConfiguration
#Configuration
#EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter{
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/resources/templates/");
resolver.setSuffix(".html");
return resolver;
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.defaultContentType(MediaType.TEXT_HTML);
}
}
If you want to see the rest of the classes, please go to my previous question everything is in there.
Thanks in advance.
In linq2sql I had this code to implement base class for repository
public abstract class Repository<T> : IRepository<T> where T : class {
protected DataContext context;
protected Table<T> table;
public Repository (DataContext context)
{
this.context = context;
table = context.GetTable<T> ();
}
public IQueryable<T> FindAll ()
{
return table;
}
public IQueryable<T> FindAll(Func<T, bool> exp)
{
return table.Where(exp).AsQueryable();
}
}
Now I need to migrate to EF 4.0
Everything is fine and simple, BUT I can't find GetTable (or similar) method in ObjectContext
Thanks for help
You're looking for CreateObjectSet<T>.