lets say you have a function fun() in class A that I want to test fun() calls 2 dependancy fun1() and fun2() now it also calls fun3() which is of the same class A.
So here is how my class looks like :
class A {
B b;
C c;
#Inject
A(B b, C c) {
this.b = b;
this.c = c;
}
fun() {
try {
b.fun1();
c.fun2("success");
} catch (Exception) {
c.fun2("Failure")
}
fun3();
}
fun3() {
//Code
}
}
The Test that I wrote :
public class ATest {
#Mock
B b;
#Mock
C c;
#InjectMocks
A a;
#Mock
Fun1Response fun1response;
#Test
public void myTest() {
when(b.fun1(any())).thenReturn(fun1response);
A aSpy = Mockito.spy(a);
doNothing().when(aSpy).fun3();
doNothing().when(c).fun2(any());
aSpy.fun();
verify(c).fun2(eq("success"));
verify(a).fun3();
}
}
It is giving me this error while runnign the test:
Wanted but not invoked:
c.fun2(<any>)
[junit] Actually, there were zero interactions with this mock.
Related
my code is structured like this
class B
{
virtual void bar() { //something};
}
class A {
void foo(B& b) { b.bar();}
}
I wanted to create a gtest mock for this but I'm running into an issue...
class Btest : public B
{
public:
MOCK_METHOD(void, bar, (), (override));
};
TEST()
{
A a;
Btest b;
a.foo(b); <--- no instance matches argument list
}
How do I implement a mock like this? If I upcast wouldn't it just call the non mocked version of that method?
There are several issues with your code. One way to fix it is to make the bar and foo methods public:
class B {
public:
virtual void bar() {
// something
}
};
class A {
public:
void foo(B& b) { b.bar(); }
};
class Btest : public B {
public:
MOCK_METHOD(void, bar, (), (override));
};
TEST(a, b) {
A a;
Btest b;
a.foo(b);
}
I have a class that I want to test.
class Myclass {
virtual int functionA (int x) {
if (x==1) {
functionB();
return 1;
}
else return 0;
}
virtual void functionB() {
// do some logic
functionC();
printf ("functionB \n"};
}
virtual void functionC() {
// do some logic
printf ("functionC \n"};
}
}
I setup a Mock class:
class MockMyClass : public Myclass {
MOCKMETHOD1(functionA, int(int x));
MOCKMETHOD0(functionB, void());
MOCKMETHOD0(functionC, void());
}
My test case in test class:
class MyTesting : public testing::Test {
virtual void SetUp(){
testObj = new MyClass();
testMock = new MockMyClass();
}
virtual void Teardown() {
delete testObj;
delete testMock;
}
}
MyClass * testObj;
MockMyClass * testMock;
TEST_F (MyClass, Test1){
EXPECT_CALL (testMock, functionB());
testObj->functionA()
}
TEST_F (MyClass, Test2){
EXPECT_CALL (testMock, functionC());
testObj->functionB()
}
TEST_F (MyClass, Test3){
EXPECT_CALL (testMock, functionC());
testObj->functionC()
}
Basically, I need to run the functionA -> functionB -> functionC.
How can write Test1 such that when have expect call of functionB, it doesn't "go further" into B and requires another expect call of function C.
In other words, how can write a Test1 such that whatever logic in functionB will be tested in Test2 and further in Test3 and Test1 just expect a call of functionB.
TEST_F (MyClass, Test1) {
InSequence seq;
EXPECT_CALL (MockMyClass, functionB());
EXPECT_CALL (MockMyClass, functionC());
testObj->functionA(1);
}
InSequence
Your example will not compile, functionA requires arg and missing semicolons.
Wrong use of inheritance is main problem here.
If your class under test is same as mock class then this should be obvious something wrong is here.
Note that here:
virtual void SetUp() {
testObj = new MyClass();
testMock = new MockMyClass();
}
there is no dependency between testObj and testMock. So Question is how testObje can impact state of testMock? It can't!
So basically problem is your code design of production code (code under test).
Since logic of this class has been obfuscated I have no clues how I could fix your code properly. I'm guessing it should be something like this:
class ISomeDependency {
public:
virtual int functionA(int x) = 0;
};
//---------
class Myclass {
public:
Myclass(ISomeDependency& dep)
: mDep { dep }
{
}
void functionB()
{
if (mDep.function(1) > 5) {
functionC();
}
}
void functionC()
{
}
private:
ISomeDependency& mDep;
};
class MyclassTest : public ::testing::Test {
void checkMyClassIsInStateX()
{
ASSERT_EQ(myClass.getX(), ...);
}
public:
MockSomeDependency mock;
Myclass myClass { mock };
};
TEST_F(MyclassTest, functionBCallsDependencyWithOneAndChangesStateToX)
{
EXPECT_CALL(mock, functionA(1)).WillOnce(Return(4));
myClass.functionB();
checkMyClassIsInStateX();
}
I am using Moq v4.13 and C#.
I am trying to test method MethodA on the interface of MyClass : IMyInterface.
MethodA has invocations on methods of another interface (IAnother) and I have set up those. These seem to be setup fine.
MethodA also invokes MethodB (also on IMyInterface) and MethodC (public, but not on IMyInterface) in MyClass.
I have set up MethodB but while testing, it seems like actual code of MethodB is invoked.
As for MethodC, I am not sure how to set that up.
public interface MyInterface
{
int MethodA();
int MethodB();
}
public class MyClass : MyInterface
{
public MyClass(IAnother b) {...}
public int MethodB(){...}
public int MethodC(){...}
public int MethodA()
{
...
var x = b.MethodX();
...
var a = MethodB();
...
var b = MethodC()
return a + b + x;
}
}
public MyInterfaceHarness
{
Mock<IAnother> _anotherMock;
public MyInterfaceHarness()
{
_anotherMock = new Mock<IAnother>();
Mocker = new AutoMocker();
}
public AutoMocker Mocker {get;}
public MyClass MethodAHarness()
{
Mocker.Use(_anotherMock) // Mocker is Automocker
_anotherMock.Setup(m => m.MethodX()).Returns(5); // this seems to be setup fine
//here I want to setup invocations to MethodB and MethodC
....
Mocker.CreateInstance<MyClass>();
}
}
[TestFixture]
public MyInterfaceTest
{
private MyInterfaceHarness _harness;
private AutoMocker _mocker;
[SetUp]
public void SetUp()
{
_harness = new MyInterfaceHarness();
_mocker = _harness.Mocker();
}
[Test]
public void Should_Test_MethodA()
{
var mi = _harness.MethodAHarness();
// use _mocker to setup other invocations that need verify
...
var i = mi.MethodA();
//asserts
...
}
}
Here I Have a class A which is implementing method1.
class A{
public void method1(String name){
classB b = new classB();
// Some operations
b.method2(argument1);
}
}
I want to capture the argument passed to method2 for which I wrote the below code.
I got the error as the mock is not invoked when I did verify to capture the argument in the below code. Please let me know how to execute this successfully by invoking the mock to capture the argument passed to method2
class ATest{
String name = "name";
#Before
public void setup{
class A = new class A();
class B = Mockito.mock(classB.class);
}
public void testmethod1()
{
A.method1(name);
ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
Mockito.verify(B, Mockito.times(1)).method2(captor.capture());
String actual = captor.getValue();
assertEquals("some data", actual);
}
}
Class B needs to be a dependency of Class A for you to be able to mock it properly. Or it can be a parameter.
Class A{
public final B b;
public A(B b){
this.b = b
}
public void method1(String name){
// Some operations
b.method2(argument1);
}
}
then in your test pass in the mock when you instantiate class A
class ATest{
private B b;
private A a;
#Before
public void setup{
b = Mockito.mock(B.class);
a = new A(b);
}
// tests...
}
class A
{
public:
void doFirstJob()
{
// Do first Job.
}
}
class B : public A
{
public:
virtual void doSecondJob()
{
// Do Second Job.
}
}
class C
{
public:
void doSomething() {
b->doFirstJob();
b->doSecondJob();
}
private:
B* b;
}
Now I should write unit test code for class C, then I'll write a mock for class B, but the problem is how to mock the method doFirstJob().
Bluntly, I want know how to mock the non-virtual method of the parent class???
Can any one help me ??
Typemock Isolator++ supports mocking non virtual methods of a parent class (same as faking a method of the class under test).
See following example:
class A
{
public:
int doFirstJob()
{
return 0;
}
};
class B : public A
{
};
class C
{
public:
int doSomething()
{
return b->doFirstJob();
}
void setB(B* to)
{
b = to;
}
private:
B* b;
};
In the test You create a fake of B -> change the behavior of doFirstJob to return 3 -> continue with your test as you would normally write it.
TEST_CLASS(NonVirtualMethod)
{
public:
TEST_METHOD(NonVirtualMethodTestOfBaseClass)
{
B* fakeB = FAKE<B>();
WHEN_CALLED(fakeB->doFirstJob()).Return(3);
C c;
c.setB(fakeB);
int first = c.doSomething();
Assert::AreEqual(3,first);
}
}
You can find more examples here.