public class FileUtil {
public void methodOne(Bean bean) {
StringBuffer profileControlValue = new StringBuffer();
profileControlValue.append(bean.getName()).append(bean.getDesc());
String sourcePath = "path to save";
try (Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(sourcePath.toString())))) {
writer.write(profileControlValue.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to write a Junit test case using Mockito/PowerMockito for above method.
Basically I have a method which accepts Bean and process the values and writes it into file.
Related
I have this RestTemplate that I want to mock and return an object based on a json file
ResponseEntity<List<Hotel>> deliveryResponse =
restTemplate.exchange(link.getHref(),
HttpMethod.GET, null, new ParameterizedTypeReference<List<Hotel>>() {
});
the mock I try:
when(restTemplate.exchange(eq("delivery"), eq(HttpMethod.GET), any(), eq(Object.class)))
.thenReturn(readObjectFromFile("hotel.json", Order.class));
and
private <T> T readObjectFromFile(final String fileName, final Class<T> clazz) {
ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.readValue(this.getClass().getClassLoader().getResourceAsStream("__files/" + fileName), clazz);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
but I have this compilation error:
Cannot resolve method 'thenReturn(T)'
I think you got a typo?
Try this.
when(restTemplate.exchange(eq("delivery"), eq(HttpMethod.GET), any(), eq(Object.class)))
.thenReturn(readObjectFromFile("hotel.json"), Order.class);
I want to bind MyImpl to Multibinding. But MyImpl's constructor takes parameter.
final Multibinder<MyInterface> binder = Multibinder.newSetBinder(binder(), MyInterface.class)
binder.addBinding().to(MyImpl.class);
public MyImpl(Boolean myParam) ...
I do not want to #Inject it because it's say boolean, which can be occasionally injected somewhere else. So. I can introduce some Enum and inject it instead, how then to do this? Or can I better just write somehow
binder.addBinding().to(MyImpl.class, true);
binder.addBinding().to(MyImpl2.class, false);
or so?
I do not want to #Inject it because it's say boolean, which can be occasionally injected somewhere else.
To avoid this, use Named Annotations.
Solution One:
#Inject
public TextEditor(#Named("OpenOffice") SpellChecker spellChecker) { ...}
Here is the binding code:
bind(SpellChecker.class).annotatedWith(Names.named("OpenOffice")).to(OpenOfficeWordSpellCheckerImpl.class);
Solution Two:
Load java-properties in a module and use the java-prop-names:
private static Properties loadProperties(String name){
Properties properties = new Properties();
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream(name);
try {
properties.load(is);
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if(is != null){
try {
is.close();
} catch (IOException dontCare) { }
}
}
return properties;
}
protected void configure() {
try{
Properties gameProperties = loadProperties("game.properties");
Names.bindProperties(binder(),gameProperties);
}catch (RuntimeException ex){
addError("Could not configure Game Properties");
};
}
I am creating a bean processor and setting setStrictHeaderValidationEnabled to true. Now my CsvParserSettings are consuming this bean processor which in turn is consumed by CSVRoutines. But on iterating through csvroutines the bean processor does not validate headers and subsequent rows get converted to beans for files with invalid headers as well
Sample Code-
final BeanProcessor<TestBean> rowProcessor = new BeanProcessor<TestBean>(TestBean.class) {
#Override
public void beanProcessed(TestBean bean, ParsingContext context) {
}
};
rowProcessor.setStrictHeaderValidationEnabled(true);
final CsvParserSettings parserSettings = new CsvParserSettings();
parserSettings.setProcessor(rowProcessor);
parserSettings.setHeaderExtractionEnabled(true);
parserSettings.getFormat().setDelimiter(',');
CsvRoutines routines = new CsvRoutines(parserSettings);
for(TestBean bean : routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8)) {
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(bean));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Note: TestBean uses #Parsed annotation of univocity to set column names.
The iterate method returns a IterableResult, which provides you the ParsingContext from which you can get the headers parsed from the input.
Try this code:
IterableResult<TestBean, ParsingContext> iterableResult = routines.iterate(TestBean.class, inputFile, StandardCharsets.UTF_8);
ResultIterator<TestBean, ParsingContext> iterator = iterableResult.iterator();
ParsingContext context = iterator.getContext();
String[] headers = context.headers();
//HEADERS HERE:
System.out.println(Arrays.toString(headers));
while(iterator.hasNext()){
try {
System.out.println(OBJECT_MAPPER.writeValueAsString(iterator.next()));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
Hope it helps
I am writing a JUnit with Mockito. But on the line
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
It calls the actual method, which is causing the test failure. Interesting point is that it directly makes the actual call at start of the test case when when()...thenReturn() statemnts gets executed. Can you please tell me how I can fix this? My test is as per below
#Test
public void testDecryptData_Success() throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException {
encryptDecryptUtil = spy(new EncryptDecryptUtil());
Key keyMock = Mockito.mock(Key.class);
when(encryptDecryptUtil.getKeyFromKeyStore(any(String.class))).thenReturn(keyMock);
String inputData = "TestMessage";
String version = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
byte[] enCryptedValue= new byte[] {9,2,5,8,9};
Cipher cipherMock = Mockito.mock(Cipher.class);
when(Cipher.getInstance(any(String.class))).thenReturn(cipherMock);
when(cipherMock.doFinal(any(byte[].class))).thenReturn(enCryptedValue);
String encryptedMessage = encryptDecryptUtil.encryptData(inputData);
assert(encryptedMessage.contains(version));
assertTrue(!encryptedMessage.contains(inputData));
}
On the third line it self, it calls the actual method.
Main code is as per below.
public class EncryptDecryptUtil {
private String publicKeyStoreFileName =
GetPropValues.getPropValue(PublisherConstants.KEYSTORE_PATH);
private String pubKeyStorePwd = "changeit";
private static final String SHA1PRNG = "SHA1PRNG";
private static final String pubKeyAlias="jceksaes";
private static final String JCEKS = "JCEKS";
private static final String AES_PADDING = "AES/CBC/PKCS5Padding";
private static final String AES = "AES";
private static final int CONST_16 = 16;
private static final int CONST_0 = 0;
private static final String KEY_STORE = "aes-keystore";
private static final String KEY_STORE_TYPE = "jck";
private static final Logger logger = Logger.getLogger(KafkaPublisher.class);
public Key getKeyFromKeyStore( String keystoreVersion) {
KeyStore keyStore = null;
Key key = null;
try {
keyStore = KeyStore.getInstance(JCEKS);
FileInputStream stream = null;
stream = new FileInputStream(publicKeyStoreFileName+KEY_STORE+PublisherConstants.UNDERSCORE+keystoreVersion+PublisherConstants.DOT+KEY_STORE_TYPE);
keyStore.load(stream, pubKeyStorePwd.toCharArray());
stream.close();
key = keyStore.getKey(pubKeyAlias, pubKeyStorePwd.toCharArray());
} catch (KeyStoreException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (CertificateException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
} catch (IOException e) {
logger.error("Error Inside getKeyFromKeyStore, Exception = " + e);
e.printStackTrace();
}
return key;
}
public String encryptData(String data) {
String keystoreVersion = GetPropValues.getPropValue(PublisherConstants.KEYSTORE_VERSION);
SecretKey secKey = new SecretKeySpec(getKeyFromKeyStore(keystoreVersion).getEncoded(), AES);
String base64EncodedEncryptedMsg = null;
Cipher cipher = null;
try { ------- Logic -------------------}
catch() { }
}
}
Have a look at the "Important gotcha on spying real objects" section of the Spy documentation.
Essentially, you cannot use the when(...).thenReturn(...) pattern with Spies, because as you have discovered, it calls the real method!
Instead, you use a different pattern which does exactly the same thing:
doReturn(...).when(spy).someMethod();
So, for your example:
doReturn(keyMock).when(encryptDecryptUtil).getKeyFromKeyStore(any(String.class));
Some advice which is unrelated to your question: If I read your code correctly, then EncryptDecryptUtil is the class that you are testing. As a general rule, you should not mock, stub, or spy on the object that you are actually testing, because then you are not testing the true object. You are actually testing a version of the object creating by the Mockito library. Furthermore, it's an uncommon pattern which will make your tests hard to read and maintain. If you find yourself having to do this, then the best thing would be to refactor your code so that the methods you are mocking (or spying on) and the methods you are testing are in different classes.
I have to process an xml against an xslt with result-document that create many xml.
As suggested here:
Catch output stream of xsl result-document
I wrote my personal URI Resolver:
public class CustomOutputURIResolver implements OutputURIResolver{
private File directoryOut;
public CustomOutputURIResolver(File directoryOut) {
super();
this.directoryOut = directoryOut;
}
public void close(Result arg0) throws TransformerException {
}
public Result resolve(String href, String base) throws TransformerException {
FileOutputStream fout = null;
try {
File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
f.getParentFile().mkdirs();
fout = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new StreamResult(fout);
}
}
that get the output directory and then saves here the files.
But then when I tested it in a junit I had some problems in the clean-up phase, when trying to delete the created files and noticed that the FileOutputStream fout is not well handled.
Trying to solve the problem gave me some thoughts:
First I came out with this idea:
public class CustomOutputURIResolver implements OutputURIResolver{
private File directoryOut;
private FileOutputStream fout
public CustomOutputURIResolver(File directoryOut) {
super();
this.directoryOut = directoryOut;
this.fout = null;
}
public void close(Result arg0) throws TransformerException {
try {
if (null != fout) {
fout.flush();
fout.close();
fout = null;
}
} catch (Exception e) {}
}
public Result resolve(String href, String base) throws TransformerException {
try {
if (null != fout) {
fout.flush();
fout.close();
}
} catch (Exception e) {}
fout = null;
try {
File f = new File(directoryOut.getAbsolutePath() + File.separator + href + File.separator + href + ".xml");
f.getParentFile().mkdirs();
fout = new FileOutputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new StreamResult(fout);
}
}
So the fileOutputStream is closed anytime another one is opened.
But:
1) I don't like this solution very much
2) what if this function is called in a multithread process? (I'm not very skilled about Saxon parsing, so i really don't know..)
3) Is there a chance to create and handle one FileOutputStream for each resolve ?
The reason close() takes a Result argument is so that you can identify which stream to close. Why not:
public void close(Result arg0) throws TransformerException {
try {
if (arg0 instanceof StreamResult) {
OutputStream os = ((StreamResult)arg0).getOutputStream();
os.flush();
os.close();
}
} catch (Exception e) {}
}
From Saxon-EE 9.5, xsl:result-document executes in a new thread, so it's very important that the OutputURIResolver should be thread-safe. Because of this change, from 9.5 an OutputURIResolver must implement an additional method getInstance() which makes it easier to manage state: if your newInstance() method actually creates a new instance, then there will be one instance of the OutputURIResolver for each result document being processed, and it can hold the output stream and close it when requested.