Mock Kotlin class in Java unit test - unit-testing

I have this Java test with Mockito:
public class PersistentNodeDeserializerTests {
#Test
public void userInfoPersistentNodeDeserializer() {
PersistentNode node = mock(PersistentNode.class);
when(node.stringChild("username")).thenReturn("cliff12");
//more stuff
}
}
PersistentNode is a Kotlin class:
open class PersistentNode(private val path: PersistentNodePath, val content: Any) {
val stringPath: String
get() = path.get()
val key: String
get() {
val parts = stringPath.split("/");
return parts[parts.size - 1];
}
val mapContent: Map<String, Any>
get() {
return content as HashMap<String, Any>
}
fun stringChild(child: String): String {
return mapContent.get(child) as String
}
}
I get this error:
kotlin.TypeCastException: null cannot be cast to non-null type
java.util.HashMap
How can I mock the property stringChild properly?

this library may solve your issue https://github.com/nhaarman/mockito-kotlin
EDIT: sorry, didn't realize you were using a Java test. If it's an option, try writing your test in kotlin too

Related

mockito, how to mock a class which is a member of the container class

With mockito-inline how to test static function (with stubbing other static function), or mock/stub some internal depended class?
Here is the sample:
Having a class Util which internally depending on java.security.MessageDigest
package java.security;
public abstract class MessageDigest extends MessageDigestSpi
... ...
public byte[] digest() {
byte[] result = engineDigest();
return result;
}
}
and the container class has a few static functions to be tested
public class Util {
public static byte[] getStringDigest(#NonNull String text, #NonNull String algorithm, #NonNull String charSet) {
if (text == null) {
return null;
}
MessageDigest messageDigest; //<== depend on
try {
messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(text.getBytes(charSet));
} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
return null;
}
return messageDigest.digest();
}
public static String generateId(#NonNull String s) {
byte[] sha1Byte = getStringDigest(s, "SHA-1", "UTF-8");
if (sha1Byte == null) {
return s;
}
// otherwise build the id
String id = buildId(sha1Byte);
return id;
}
}
would like to test the Utils.generateId(#NonNull String s) with stubbing getStringDigest() returning null, so that sometext is expected to return.
since it is static function so it was tested with powermock.
#Test
public test_util_1{
PowerMockito.mockStatic(MessageDigest.class);
String sometext = "sometext";
PowerMockito.when(Util.getStringDigest(sometext, "SHA-1", "UTF-8")).thenReturn(null);
assertEquals(sometext, Util.generateId(sometext));
}
with mock stub, when Util.getStringDigest() is called null is returned.
It worked fine.
now the mockito-inline supports testing static function (and it has problem to mix with powermockito2 when testing kotlin etc.) so the powermock is removed.
Tried with mockito-inline 3.8.0
#Test
public void test_util_1() {
String sometext = "sometext";
try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
utilMoc.when(() -> Util.getStringDigest(sometext, "SHA-1", "UTF-8"))
.thenReturn(null);
assertEquals(sometext, Util.generateId(sometext));
}
got error:
java.lang.AssertionError: Unexpected value
Expected :sometext
Actual :null
the Util.generateId(sometext) returns null (not the sometext).
when using assertEquals(sometext, sutilMoc.generateId(sometext)); it cannt compile and says cannt resolve the generateId().
How to use mockito-inline to test the static function?
Or if there is way to mock/stub the depended abstract class MessageDigest for stub the digest() to return null, but dont know is it possible?
found a way to make the test work (using .thenCallRealMethod()),
but still not find a way to mock the depended class which is instantiated inside the static function. if anyone knows a solution for that?
#Test
public void test_util_1() {
String sometext = "sometext";
try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
utilMoc.when(() -> Util.getStringDigest(anyString(), anyString(), anyString()))
.thenReturn(null);
// need to tell mock to call the original, otherwise a default mocked stub will be called
utilMoc.when(() -> Util.generateId(anyString()))
.thenCallRealMethod();
assertEquals(sometext, Util.generateId(sometext));
}

Mocking Java 8 lamba function with Mockito 2

I am using JDBI 3 and have written the following utility function.
public class JdbiHelper {
// ...
public <T, DAO> T fetch(final Function<DAO, T> function, Class<DAO> daoClass) {
return dbi.withHandle(handle -> {
final DAO dao = handle.attach(daoClass);
try {
return function.apply(dao);
}
finally {
handle.close();
}
});
}
}
which I can call in methods like this
public Optional<Account> findByEmailAddress(final String emailAddress) {
if (!exists(emailAddress))
return Optional.empty();
return jdbiHelper.fetch(dao -> ofNullable(dao.selectByEmailAddress(emailAddress)), AccountDAO.class);
}
private boolean exists(final String emailAddress) {
return jdbiHelper.fetch(dao -> dao.count(emailAddress) > 0, AccountDAO.class);
}
I am trying to write a test for the findByEmailAddress mocking jdbiHelper using Mockito 2 but cannot work out how to mock the dao -> part of the method.
I've tried using jdbiHelper.fetch(any(Function.class), eq(AccountDAO.class)) but as there are two different expectations of what to return it fails trying to cast one or the other.
Passing in a mocked Function causes a NPE as the dao param is null.

How to use Microsoft Fakes framework to shim an instance method?

I am using Microsoft Fakes framework within VS2012.
I use the following code to shim instance methods of my type.
using (ShimsContext.Create())
{
ShimDateTime.NowGet = () => { return new DateTime(1949, 10, 1); };
DateTime now = DateTime.Now; // shim works for the static property DateTime.Now.
Class1 dependency = new Class1();
using (ShimsContext.Create())
{
ShimClass1 shim1 = new ShimClass1();
StubClass1 stub1 = new StubClass1();
shim1.method1 = () => { return "shim method1"; };
shim1.IMethod1 = () => { return "shim IMethod1"; };
String s1 = dependency.method1();// shim doesn't work for the instance method.
String s2 = dependency.IMethod1();// shim doesn't work for the instance method.
}
The class1 and looks like this:
public class Class1 : Interface1
{
public String method1()
{
return "real method1";
}
//Interface 1 member
public string IMethod1()
{
return "real IMethod1";
}
}
I expect the s1 and s2 to be the shimed output, but it is still real output.
Why?
If 'method1' was static your shim would have worked. However with the current code you have not really shimmed out 'method1'. You need to either associate the instance with the shim instance
Class1 dependency = new ShimClass1() { Method1 = () => { return "Shim.Method1"; } };
or associate all instance methods with your delegate
ShimClass1.AllInstances.Method1 = (q)=> { return "Shim.Method1"; };
Also I dont see the need to have the ShimsContext.Create() done twice
If you want to use stubs to redirect IMethod1 you should be consuming the StubInterface1 instead
Class1 dependency = new StubInterface1() { Method1 = () { return ""; } };
Variations of these are available on msdn for reference

Using Microsoft Fakes to Shim a method with ref parameters

I have a static method with ref parameters in my legacy (untestable) dll. I am trying to write unit tests for a class that calls into this method.
public static class Branding
{
...
...
static public bool GetBranding(Int32 providerId,
Int32 employerId,
string brandingElement,
ref string brandingValue)
...
...
}
I need help writing a shim statement for this call
ShimBranding.GetBrandingInt32Int32StringStringRef =
( providerId, employerId, element, { ====> WHAT GOES HERE <===== } )
=>
true;
Thanks!
using (ShimsContext.Create())
{
ShimBranding.GetBrandingInt32Int32StringStringRef =
(int providerId, int employerId, string brandingElement, ref string brandingValue) =>
{
brandingValue = "Blah";
return true;
};
}

groovy regex test failing

In my Grails 1.3.6 app I've written this class
import org.apache.commons.lang.StringUtils
/**
* Implementation that converts a name such as <tt>FOO_BAR</tt> to <tt>fooBar</tt>
*/
#Singleton
class CamelCaseEnumTransformer implements EnumTransformer {
String transformName(Enum e) {
String transformedName = e.name().toLowerCase()
transformedName.replaceAll(/_([a-z])/) {
it[1].toUpperCase()
}
StringUtils.remove(transformedName, '_')
}
}
I've created this test case:
class EnumTransformerTests extends GroovyTestCase {
private static enum TestEnum {
A, FOO, FOO_BAR, FOO_BAR_123,
}
void testCamelCaseTransformer() {
EnumTransformer transformer = CamelCaseEnumTransformer.instance
assertEquals 'a', transformer.transformName(TestEnum.A)
assertEquals 'foo', transformer.transformName(TestEnum.FOO)
// This test fails on the line below
assertEquals 'fooBar', transformer.transformName(TestEnum.FOO_BAR)
}
}
The test fails on the line marked above. I reckon the problem must be related to the replaceAll method, because this is the first time that the closure passed as the second argument to this method is executed.
The error I get is:
groovy.lang.MissingMethodException: No signature of method:
CamelCaseEnumTransformer$_transformName_closure1.doCall()
is applicable for argument types: (java.lang.String, java.lang.String) values: [_b, b]
What's particularly strange, is that if I run the equivalent code below in the Groovy console, everything seems to work fine.
#Singleton
class CamelCaseEnumTransformer {
String transformName(Enum e) {
String transformedName = e.name().toLowerCase()
transformedName.replaceAll(/_([a-z])/) {
it[1].toUpperCase()
}
}
}
enum TestEnum {
A, FOO, FOO_BAR, FOO_BAR_123,
}
def transformer = CamelCaseEnumTransformer.instance
assert 'fooBar' == transformer.transformName(TestEnum.FOO_BAR)
From the error message text, it looks like the closure should accept 2 arguments for the 2 matches in your regex. Try the following:
transformedName.replaceAll(/_([a-z])/) { wholeMatch, capturedGroups ->
capturedGroups[0].toUpperCase();
}