Mocking aggregate classes - unit-testing

we have the following method inside class C:
public static void m(a A, b B)
{
......
A1 a1=new a.getA1; //Not sure about the syntax
Double d1= a.getInfo;
.....
if (d1>5.0)
{
b.add(d1,a1)
}
}
A is another class. Inside A, we have a variable declared as type of class A1 (this makes A an aggregated class I think). I have defined the following as mock objects:
private mockA = mock(A.class);
private mockA1 = mock(A1.class); // Please help with syntax
private mockB = mock(B.class)
Also
when(mockA.getInfo()).thenReturn(6.4);
when(mockA.getA1()).thenReturn(mockA1); //Please help with syntax
when(mockA1.m2()).thenReturn("Some More Details"); // Please help with syntax
m(mockA, mockB);
// In case > 5.0
verify(mockB,times(1)).add(6.4,mockB);
//in case < 5.0
verify(mockB,times(0)).add(anyDouble,any(B.class));
Could you please help if the syntax for mocking A1 object, and using it in when/verify is correct?
Another question is if it is not necessary to create mock for a1, which syntax should be used? For example, is the following ok?
when(mockA.getA1().m2())).thenReturn("Something");
Thanks

The syntax for mocking A1 is no different than for mocking A. You just need to make sure that any interactions with A1 (e.g. mockA1.m2()) are either mocked or contain valid data (if A1 isn't a mock).
If you're mocking A1, then your code is correct:
A mockA = mock(A.class);
A1 mockA1 = mock(A1.class);
when(mockA.getInfo()).thenReturn(6.4);
when(mockA.getA1()).thenReturn(mockA1);
when(mockA1.m2()).thenReturn("Some More Details");
If A1 is not a mock, then you don't need to mock its methods like is done with when(mockA1.m2()).thenReturn(...) above:
A mockA = mock(A.class);
A1 realA1 = new A1();
when(mockA.getInfo()).thenReturn(6.4);
when(mockA.getA1()).thenReturn(realA1);

Related

whenNew in Kotlin unit test & Missing calls inside every block

Specifically asking, is there a Kotlin version for this java statement?
whenNew(myClass.class).withAnyArguments().thenReturn(myObject);
I have looked everywhere and haven't found anything that has worked for me yet.
I have tried:
every { myClass(any(), any()) } returns myObject
To this I get this error - argumentA must be in the form m.n. This tells me that blank arguments are being fed to myClass constructor but this is not my motive. I want this class to always return myObject whenever a constructor is being called, irrespective of the arguments.
I have also tried this:
every { myClass(TEST_A, TEST_B) } returns myObject
Then I get this error - Missing calls inside every { ... } block.
Another key point to add is - this is not the class I am writing the test for. I am writing the test cases for myOtherClass (actually defined in kotlin as an object, see below). Within one of the methods in myOtherClass, myClass is instantiated by feeding a set of arguments to its public constructor.
object myOtherClass {
fun mainFunction(a: A, b: B): X {
val answer = getAnswer(a, b)
y = convertAnswerToX(answer)
return y
}
private fun getAnswer(a: A, b: B): myClass {
val a1 = doSomethingToA(a)
val b1 = doSomethingToB(b)
return myClass(a1, b1)
}
}

Using spy to mock a full object created in the class which is tested

I have the following structure:
class A {
public A(String p){
// ...
}
public String AMethod(String p){
// ...
}
}
class B {
int method(String param){
A a = new A(param); int n;
String s = A.AMethod(param);
// ... (initializes n, ...)
return n;
}
}
Now I want to test method in class B but control the output of AMethod when it is called. But since I do not create the object A in the test class of B, I cannot mock it normally - how can I mock object A instead?
I tried Mockito.spy but it doesn't seem to work:
this.ASpy = spy(new A());
when(ASpy.createSession(any())).then(invocation -> {
// ... (*)
});
(*) still doen't get called... but spy should be the right solution, shouldn't it? My problem is: I never create an object A in my test class, only in method such an object is created but not in the test class.
The best way to handle this (if possible) would be to modify the code of class B so that object A was injected into the method (passed as a parameter, set as a class field or instantiated with usage of a factory class - the factory would be injected as a field and the factory object could be mocked in the test to return a mocked object A).
If actual code modifications are not possible, you could use PowerMock's whenNew method and return a mocked object in your test.
A side note: if you're using JUnit 5, PowerMock may not be a viable solution - read more here.

Mock class object as parameter of function

I am using junit and mokito to write unit test of my java program.
public MyClass {
private ClassA a;
public void process(ClassB b) {
if(b.method()) a = ClassA.builder().build();
}
}
Now I have write a MockClassA and MockClassB. But I don't know how to :
Pass a MockClassB instantiation to process function
How to verify whether private variable a is set successfully
Can anybody help?
You can use something like:
#Test
public void shouldDoSomething() {
// given
ClassB mock = Mockito.mock(ClassB.class);
Mockito.when(mock.method()).thenReturn(true);
MyClass classUnderTest = new MyClass();
// when
classUnderTest.process(mock);
// then
// Insert assertions
}
However, if your field is private you are unable to test it properly. You should provide a getter for this field if you want to make some assertions against it.
But remember that internal representation of MyClass should not be tested, only the behavior of it so maybe you want to try different approach

Google Mock for NonVirtual and Private Functions

I'm attempting to write Mocks for Private / Non Virtual / Static functions and come across a way to do the same.
Here is how it looks like..
Lets assume that I have a class A which needs to be mocked and used inside class UsingA. The definition of both classes looks like
class A
{
friend class UsingA;
int privateFn() {}
public:
int nonVirtual() {}
};
// The UsingA class
class UsingA {
A &a1;
public:
UsingA(A & _a1) : a1(_a1) {}
int CallFn() {
return a1.nonVirtual();
}
int CallFn2() {
return a1.privateFn();
}
};
I know that Mocks are meant for generating the behavior of the class and while creating Mocks, we need to derive from the original class.
However, to Mock the behavior I decided not to derive from the original class, instead comment the class A and generate a Mock class with the same Name i.e class A.
Here is how my mock class looks like
// Original class A is commented / header file removed
class A {
public:
MOCK_METHOD0(nonVirtual, int());
MOCK_METHOD0(privateFn, int());
};
And my tests are usual mock tests
TEST(MyMockTest, NonVirtualTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, nonVirtual())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn();
EXPECT_EQ(retVal,100);
}
TEST(MyMockTest, PrivateTest) {
A mstat;
UsingA ua(mstat);
EXPECT_CALL(mstat, privateFn())
.Times(1)
.WillOnce(Return(100));
int retVal = ua.CallFn2();
EXPECT_EQ(retVal,100);
}
And everything works fine and I'm able to test UsingA by this mock.
Question is.
This looks easier and serves the purpose, still I haven't seen this kind of examples while browsing for google mock examples. Is there anything that would go wrong if I do this?
Honestly, I didn't find any.
NOTE: Folks, I'm using friend for demonstration only. My actual use case is totally different. Thanks
The wrong is that you are not testing real code, because of that:
comment the class A
generate a Mock class with the same name
These operations alter the code under test.
An example what can go wrong:
Change return type: long nonVirtual in Mock - previously was int
Test that on, let say, nonVirtual() == 0xFF'FFFF'FFFF (which is bigger than INTMAX) some action is being done
Forget to change in real A - so real UsingA have branch that is tested but never reachable in real code
An example code:
class A {
public:
MOCK_METHOD0(nonVirtual, long()); // change
MOCK_METHOD0(privateFn, int());
};
void UsingA::processA()
{
if (a.nonVirtual() > VERY_BIG_NUMBER)
{
throw runtime_error("oops");
}
}
TEST_F(UsingATest, throwOnVeryBigNumber)
{
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VERY_BIG_NUMBER + 1));
ASSERT_THROW(objectUndertTest.processA());
}
But real A did not change - so we test non reachable code in UsingA class:
class A {
public:
int nonVirtual(); // not changed
...
};
The best solution is (in order):
To test in isolation you have to isolate classes - so to use dependency injection (virtual functions etc, base interfaces, etc...) - this is sometimes called London School of TDD
Test both classes A and UsingA w/o any stubbing - test them together in one testcase - thus you test real code - this is called Detroit Shool of TDD
Separate by template code with good restriction on interface - this approach is most similar to yours:
Regarding 3 - you might use something like this:
template <class T = A>
class UsingA {
T &a1;
public:
UsingA(T & _a1) : a1(_a1) {}
long CallFn() {
using ANonVirtualResult = std::invoke_result_t<&T::nonVirtual>;
static_assert(std::is_same<long, ANonVirtualResult>::value);
return a1.nonVirtual();
}
...
};
And in test:
class UsingATest : public ::testing::Test
{
protected:
StrictMock<AMock> aMock;
using ClassUnderTest = UsingA<AMock>;
ClassUnderTest objectUnderTest{aMock};
};
TEST_F(UsingATest, useNonVirtual)
{
const auto VALUE = 123456;
EXPECT_CALL(aMock, nonVirtual()).WillOnce(Return(VALUE));
ASSERT_EQ(VALUE, objectUnderTest.CallFn());
}
You might note that some assumption about A might be tested during compilation as static_assert or via some SFINAE technics (more complicated).
Actually, there are examples with template code in googlemock as workaround for mocking classes w/o virtual functions.
We use your type of using mocks inside a few of our test projects to check callbacks on a larger class that we pass along using dependency injection. In our case, the methods are declared virtual.
In your case, they are not. Your mock implementation would hide the original implementation - if there was any. So I don't think there's an issue here.

Unit test a variable for both true and false

I'm working on a C++ production code here with googletest/googlemock. I've stumble upon this idea when working with one of the function in A.cpp:
bool A::process_(false);
bool A::process()
{
if ( !process_ ){
process_ = true;
}
return process_;
}
where the header contains:
protected:
static bool process_;
public:
static bool process();
I am stuck in a way that I can only test the function for an expected output of true or an input of false like so:
TEST(ATest, processVal){
A a;
EXPECT_TRUE(a.process());
}
Is there a way to test the function so that both *true* and *false* value of process_ is passed ? So that the test covers the decision for both.
I was thinking mocking so that it can expect a call for both true and false but because it is not a function in a member of a class, I guess you can not do mocking for process_ ?
If you can, how to mock the variable?
Note: I'm on linux and gcc :) thank you !
Solution1: To access any protected attribute/method from a test
without modifying production code
You can easily modify _process even if protected, just do this:
class SubA : public A
{
public:
void setProcess( bool val ) { process_ = val; }
};
A a;
SubA* pA = (SubA*) &a;
pA->setProcess( false );
This will work pretty well and is safe. Even if you are casting A* to SubA* which is not really valid, it will work as SubA objects in memory are the same as A objects (as SubA does not declare any extra attribute).
This only works because process_ is protected, so you create a derived class SubA and use it because compiler will allow this subclass to access the protected stuff.
Solution2: To access any protected and even private attribute/method from a test without modifying production code
Now, if process_ was private, this would not work...but, private/protected is only managed by the compiler...the attributes are here in memory and you may access them even if you are not "allowed to".
It's ugly but works perfectly:
#define protected public
#define private public
#include "A.h"
#undef private
#undef protected
{
A a;
a._process = false;
}
This hack makes it easy to access any private/protected attributes/functions from your test programs.
Declare a subclass of A. Since process_ is protected, you can use the subclass of A to set it totrueorfalse`, before running the test.