Have a problem with mocking the inline function with lambda. Have class UserController, trying to mock tracer with function createSpan.
UserController class:
class UserController(private val tracer:Tracer) {
fun subscribeUser() {
tracer.createSpan("GraphDB: subscribedUser") {
do something...
}
}
}
createSpan inline function:
inline fun <T> Tracer.createSpan(operationName: String, block: SpanContext.() -> T): T =
buildSpan(operationName)
.start()
.useOn(this, block)
Tried:
Mockito.`when`(mockTracer.createSpan<Any>(any(), any())).thenReturn(mockSpanContext)
returns org.mockito.exceptions.misusing.InvalidUseOfMatchersException
Mockito.`when`(mockTracer.createSpan<SpanContext>("GraphDB: subscribedUser", any())).thenReturn(mockSpanContext)
returns java.lang.NullPointerException
Tried different approaches but return only org.mockito.exceptions.misusing.InvalidUseOfMatchersException or java.lang.NullPointerException.
How can I mock this inline function with a lambda or just ignore it, because I don't want to test this function? Any help appreciated.
Related
I have a struct:
type foo struct {
bar mockableInterface // some interface that I can mock
}
func (f *foo) DoSmth1() []interface{} {
return f.bar.Bar()
}
func (f *foo) DoSmth2() []interface{} {
res := f.DoSmth1()
//some code to test
}
Here I have no problem with mocking bar and testing DoSmth1(). But it's not obvious how to test DoSmth2().
Should I rewrite this method to make it testable or rewrite tests somehow?
#mkopriva recommended just to mock Bar() call in DoSmth2() test. But in this case I would rewrite tests for all method that calls DoSmth1() every time it changes. So I've come to the following solution. We can encapsulate this mock logic in one method:
func (s *TestSuite) ExpectDoSmth1(times int, in, out []interface{}) {
s.barMock.Expect().Bar(in...).Times(times).Return(out...)
}
This way we can change only this method if DoSmth1() implementation changes, till its API stays the same
I'm having a hard time trying to get a private method in Kotlin using reflection in order to pass it as a parameter to a higher order function, here is what I got and what I need to do:
The function that gets the private method, probably what I should change or fix:
inline fun <reified T> T.getPrivateFunc(name: String): KFunction<*> {
return T::class.declaredMemberFunctions.first {
it.name == name
}.apply {
isAccessible = true
}
}
This is the high order function I have:
class MyService {
fun myHigherOrderFunction(action: () -> Unit) { /*...*/ }
}
These are the class and the private method I need to get somehow:
class SystemUnderTest {
fun privateFunc() { /*...*/ }
}
Finally a unit test where I I'm trying to make sure the proper method is passed to the high order function, I omitted details for simplification:
// ...
val serviceMock = MyService()
val sut = SystemUnderTest()
// Here is what I'm trying to accomplish
val privateMethod = sut.getPrivateMethod("privateFunc")
service.myHighOrderFunction(privateMethod)
// In the above line I get a compilation error: required () - Unit, found KFunction<*>
service.myHigherOrderFunction(privateMethod as () -> Unit)
// In the above line I get the following runtime error:
// ClassCastException: kotlin.reflect.jvm.internal.KFunctionImpl cannot be cast to kotlin.jvm.functions.Function1
I know the test can be done having the privateFunc as public and maybe annotating it with #VisibleForTesting, but what I want is to avoid compromising the design as long as I can.
Any ideas? Thanks in advance!
I don't think KFunction and KCallable have any notion of a bound receiver, so they are not invokable (have no operator fun invoke), and therefore don't qualify as functions. So I think you have to wrap the KFunction object in a function to be able to pass it to your higher order function. To call a KFunction, you pass the instance of the receiver class as the first argument.
val serviceMock = MyService()
val sut = SystemUnderTest()
val privateMethod = sut.getPrivateMethod("privateFunc")
service.myHighOrderFunction { privateMethod.call(sut) }
Edit: To internalize the creation of the wrapped function, you could do this:
inline fun <reified T> T.getZeroArgPrivateMethod(name: String): () -> Unit = {
T::class.declaredMemberFunctions.first {
it.name == name
}.apply {
isAccessible = true
}.call(this)
}
//...
val serviceMock = MyService()
val sut = SystemUnderTest()
val privateMethod = sut.getZeroArgPrivateMethod("privateFunc")
service.myHighOrderFunction(privateMethod)
bool Test::someFun() {
if (libFunction([](bool b) {
if (b) {
doThisWork();
} else {
doThatWork();
}
})) {
return true;
} else return false;
}
signature of libFunction is:
typedef void (*FUN)(bool);
bool libFunction(FUN f);
Hi Guys,
I need to test someFun function using Gtest/GMOCK. i need to mock libFunction which is written in C.
this libFunction takes a callback(lambda) argument.
Could you please help me with below 2 queries.
how to mock a C function (libFunction) ?
how to test callback which is passed as argument to libFunction as my actual implementation is in lambda which is need to be tested. is there a way to replace libFunction definition with dummy definition so that at run time of test case my dummy implementation will call instead of actual one and i can simulate the libFunction behaviour in dummy function.
Could to please suggest better way to test this.
I need to mock the behavior of a static method inside a non-static factory class. The implementation of the class is:
ABCFactory.java
public class ABCFactory extends BaseUserFactory
{
private static final ABCFactory factory = new ABCFactory();
public static final ABCFactory getFactory()
{
return factory;
}
public Context getContext(String authority)
{
return (Context)createInstance(authority);
}
private ABCFactory()
{
}
protected Class getInterface()
{
return ABCFactory.class;
}
}
Now, this class is used in my code to get the profile something like:
Document.java:
Profile profile = ABCFactory.getFactory().getContext(authority).currentProfile();
I need to mock the ABCFactory class so that I can send my own context/profile object as a return type while testing. I've tried a bunch of methods but nothing seems to work here. Here's what I tried in my junit test class.
Try 1:
DocumentTest.java
ABCFactory mockABCFactory = Mockito.mock(ABCFactory.class);
ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
Mockito.when(mockABCFactory .getFactory()).thenReturn(null);
Mockito.when(mockABCFactory .getContext(domain)).thenReturn(null);
Error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
Try 2: (Using PowerMock to avoid the new call.
DocumentTest.java
ABCFactory mockABCFactory = Mockito.mock(ABCFactory.class);
ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
try
{
PowerMockito.whenNew(ABCFactory.class).withNoArguments().thenReturn(mockABCFactory);
PowerMockito.when(ABCFactory.getFactory()).thenReturn(mockABCFactory);
}
catch (Exception e)
{
e.printStackTrace();
}
Mockito.when(mockABCFactory.getContext(domain)).thenReturn(null);
Error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:490)
Try 3: (Used PowerMock.mockStatic)
DocumentTest.java
ABCFactory mockABCFactory= Mockito.mock(ABCFactory.class);
ServiceProviderRegistrar.getRegistrar().bind(ABCFactory.class).toMockInstance(mockABCFactory);
try
{
PowerMockito.whenNew(ABCFactory.class).withNoArguments().thenReturn(mockABCFactory);
PowerMockito.mockStatic(ABCFactory.class);
PowerMockito.when(ABCFactory.getFactory()).thenReturn(mockABCFactory);
}
catch (Exception e)
{
e.printStackTrace();
}
Mockito.when(mockABCFactory.getContext(domain)).thenReturn(null);
Error:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:490)
What am I missing here. I have tried several other ways but ABCFactory.getFactory() always returns a new object but not my mocked object. How do I mock the behavior of ABCFactory class without changing its implementation?! Please help.
Did you use following annotations.
#RunWith(PowerMockRunner.class)
#PrepareForTest( ABCFactory.class )
I tried and following code works.
DocumentTest.class
#RunWith(PowerMockRunner.class)
#PrepareForTest( ABCFactory.class )
public class DocumentTest
{
/** Unit under test. */
private Document user;
#Before public void setUp() {
user = new Document();
ABCFactory abc = ABCFactory.getFactory();
PowerMockito.mockStatic(ABCFactory.class);
PowerMockito.when(ABCFactory.getFactory()).thenReturn(abc);
}
#Test public void testABC() {
assertEquals("", user.useFactory() );
}
}
Document class
public class Document
{
public String useFactory(){
String profile = ABCFactory.getFactory().getContext("");
return profile;
}
}
I'm working with Golang, and currently I'm doing some fun unit test with Testify, my file look like this
type myStruct struct {
field_1 string
}
func (self *myStruct) writeFirst() {
//doing something
//modify field_1
self.writeSecond()
}
func (self *myStruct) writeSecond() {
//doing something
}
In this case I'm testing writeFirst() but I'm trying to replace writeSecond() because it is using http stuff that I don't want to use because it access to internet.
I think that use a second struct and set myStruct as anonymous field will be the solution, but it's not working because me second struct and myStruct have a diferent context.
In this case I can't use mocks cause writeSecond is a method of the struct.
My test case looks like this:
func TestWriteFirst(t *testing.T) {
myStc := myStruct{}
assert.Equal(t,"My response", myStc.field_1)
}
All that I want is testing writeFirst without pass to writeSecond()
To illustrate the kind of refactoring mentioned by Not-a-Golfer in the comments, you could consider calling your second function only on an instance that is an interface:
type F2er interface {
Func2()
}
type S struct{ _f2 F2er }
var s = &S{}
func (s *S) f2() F2er {
if s._f2 == nil {
return s
}
return s._f2
}
func (s *S) Func1() {
fmt.Println("s.Func1")
s.f2().Func2()
}
Here: Func1 calls Func2 on s.f2(), not directly s.
If nothing has been set in s, s.f2() returns... itself: s
if s._f2 was replaced by any other struct which implements Func2, s.f2() returns that instance instead of itself.
See a complete example in this playground script.
Output:
TestFunc1
s.Func1
s.Func2
TestFunc1bis
s.Func1
testS.Func2 <=== different Func2 call