How to mock a method of the same class? - unit-testing

In the testing method, there are methods of the same class. How to mock the methods of the same class?
An example is as follows.
I am testing method2. It involves method1 which is in the same class. How to mock this method1?
public class A
{
public void method1(int a, int b){
}
public void method2(){
int value = method1(10,20);
}
}

You can use a Spy to do this, in combination with doReturn to stub out the method for which you want to provide canned behavior. There are many examples available on how to use a spy. Check out these tutorials and documentation:
Mockito: mocking a method of same class called by method under test when using #InjectMocks
https://www.baeldung.com/mockito-spy
Mockito: Trying to spy on method is calling the original method
Example:
List list = new LinkedList();
List spy = spy(list);
//Use doReturn to change the behavior of a method call
doReturn("foo").when(spy).get(0);

Related

Ignore method calls inside constructor for testing constructor method with Mockito and Junit4

how are you?
I'm trying to implement an unitary test for a class constructor. I can't modify the code of the class i'm testing.
The scenario i'm dealing with looks like this:
The class
public ClassIWantToTest{
//Class constructor
public void ClassIWantToTest(){
...
methodA();
...
methodB();
...
}
public void methodA(){
//do something...
}
public void methodB(){
//do something...
}
}
The test
#Test
public void testForConstructor(){
Atribute1 atb1 = mock(...);
Atribute2 atb2 = mock(...);
ClassIWantToTest c = new ClassIWantToTest();
doNothing().when(c).methodA();
doNothing().when(c).methodB();
assertEquals("atb1",atb1);
assertEquals("atb2",atb2);
...
}
methodA() and methodB() are void. I want to ignore them and just check if the atributes got correctly inserted in the class object instance I've created. I can't figure out how to do this since methodA and methodB are called in the constructor and I cant test the constructor without calling it. I also can't call "doNothing()" for methodA() and methodB() since an ClassIWantToTest mock needs to be created for the "doNothing()" call.
I tried to create a ClassIWantToTest mock and use "doCallRealMethod()" for the constructor test, but I cant call the constructor method for mocked object instances.
I would be grateful if someone could help me.
I tried to create a ClassIWantToTest mock and use "doCallRealMethod()" for the constructor call(since I want to test this call) and use "doNothing()" for the methodA() and methodB() calls, but I cant call the constructor method for mocked object instances. Doing this I wanted to call the constructor method and ignore the methodA() and methodB() with the doNothing().

Mocking External Dependency object created inside a function without dependency injection in c++

I am trying to write unit tests in C++ and am facing an issue with creating mock objects for an external dependency using Fakeit. So we have a class similar to the following:
class A
{
int test_method()
{
B obj;
return obj.sendInt()
}
};
class B
{
int sendInt()
{
return 5;
}
};
Now let's say I want to write a unit test for test_method() of class A. When we call obj.sendInt() I want to mock it and return a different value. I tried using fakeit but was not able to arrive at a solution.
I know this will be solved if we try to do a dependency injection of B via constructor or in setter methods, but I don't want to do it as it would take some refactoring in existing consumers of A.
For a similar scenario in Java, I would use PowerMockito and achieve the same using PowerMockito.whenNew
B mock = Mockito.mock(B.class);
PowerMockito.whenNew(B.class).withAnyArguments().thenReturn(mock);
Mockito.when(mock.test()).thenReturn(2);
A obj=new A();
assertEquals(obj.test(), 2);
The easiest way would be to use dependency injection. I don't think there's anything similar to PowerMockito for C++ (e.g. it's impossible to mock static methods/functions in a similar manner as PowerMockito allows for java).
If the issue is only with the dependency injection via ctor or setter methods, consider using hi-perf dependency injection, i.e. inject mock using templates.
If the class A cannot be modified at all but you own the class B, consider moving class B to a separate static library: one for production (say, libBprod) and one for testing (libBtest). In production you can link against the libBprod and in tests against libBtest. In libBtest, you can make class B a singleton under the hood. This is quite a lot of work though.
If both class A and class B cannot be modified, then I'm out of ideas - you need to refactor some part of the code somehow.
I moved the code which initializes B and invokes its method to a private method and mocked this private method using gmock
class A
{
int test_method()
{
return getBValue();
}
int getBValue()
{
B obj;
return obj.sendInt()
}
}
My Test Method looks like,
Class MockA :: A
{
public:
MOCK_METHOD(int,getBValue,(),override);
}
TEST_CASE("Test1")
{
MockA mock;
ON_CALL(mock, getBValue()).WillByDefault(Return(10));
REQUIRE(mock.test_method()==10);
}

Overriding protected abstract method in NSubstitute

I want to create a spy using NSubstitute, but can't find out how after a lot of googling and reading the docs.
The idea would be to have the substitute with an overriden method that I could use to monitor received calls, etc. as usual with mocking. But how to achieve this with NSubstitute?
I would prefer not to relax neither protected nor abstract modifiers.
Here's what I would like to do:
[Test]
public void Items_Add_shouldCall_ItemAddedMethod()
{
var sut = Substitute.For<ItemsRepository>();
// how to configure???
sut.Items.Add(Substitute.For<IItem>());
sut.Received().ItemAdded(); // currently cannot do this
// ...
public abstract class ItemsRepository
{
public ObservableCollection<IItem> Items { get; set; }
= new ObservableCollection<IItem>();
// ...
protected abstract void ItemAdded();
}
The NSubstitute API relies on calling a method to configure it with Returns or check Received() calls, which means for standard use we can only work with calls that can be invoked via the public API (which excludes protected and private members). There is no problem with the abstract part of your question; it is fine to use NSubstitute with accessible abstract members.
Even though C#, by design, prevents us from interacting directly with protected members, NSubstitute still records calls made to these members. We can check these by using the "unofficial" .ReceivedCalls() extension:
public abstract class ItemsRepository {
public virtual void Add(int i) { ItemAdded(); }
protected abstract void ItemAdded();
}
public class Fixture {
[Fact]
public void CheckProtectedCall() {
var sub = Substitute.For<ItemsRepository>();
sub.When(x => x.Add(Arg.Any<int>())).CallBase();
sub.Add(42);
var called = sub.ReceivedCalls().Select(x => x.GetMethodInfo().Name);
Assert.Contains("ItemAdded", called);
}
}
Other options include creating a derived class (as #Nkosi pointed out), or making the member internal instead of protected and using InternalsVisibleTo to make the member accessible to your test code (if you do the latter I recommend installing NSubstitute.Analyzer to help ensure this is configured correctly).

Mocking a parameterized constructor using powermockito

Consider the code given below:
#Override
public void A() {
objectA = objectB.B();
objectA.C(someValue);
objectC = new constructor(objectA,callback());
//Rest of the code
}
}
public Callback callback() {
return new callback() {
#Override
public void someMethod(someArgument) {
//some Code
}
};
}
I am trying to write a unit test case where:
the call objectB.B() has to be mocked
the call to the constructor has to be mocked
This is what I have done using Mockito and Powermockito:
#InjectMocks
ClassBeingTested testObject;
#Mock
ClassB objectB;
#Mock
ClassC objectC;
#Before()
public void setup() {
when(objectB.B()).thenReturn(new ObjectA("someValue"));
whenNew(objectC.class).withArguments(any(),any()).thenReturn(objectC);
}
#Test()
public void testMethod() {
testObject.A();
}
The first mock successfully works but the second mock using whenNew fails with the following error:
org.powermock.reflect.exceptions.ConstructorNotFoundException: No constructor found in class 'ClassC' with parameter types: [ null ]
If I use withArguments(objectA, callback()) where I have the implementation of callback in my test class, the actual constructor is called.
I want to mock the constructor call and restrict the call to the actual constructor. How can I do that?
I can not edit the code design since that is out of my scope.
In short, you get the error due to usage of 2 generic any() matchers.
When you use .withArguments(...) and set both as any() it implies
.withArguments(null, null) (since any() may match pretty much anything including nulls) which folds eventually as a single null and reflection api (which PowerMock heavily relies on) fails to discover a suitable constructor for ClassC(null).
You may check out the source of org.powermock.api.mockito.internal.expectation.AbstractConstructorExpectationSetup<T>
source that does the job
To fix up the issue consider using either .withAnyArguments() if you do not care of param types and stubbing all available constructors OR specify more concrete types while using any() like so
whenNew(ClassC.class).withArguments(any(ClassA.class), any(Callback.class))

Why it doesn't throw any exceptions when attempting to mock a singleton using either Mockito or PowerMock?

I have a singleton class "Fake"
public class Fake{
private static Fake instance;
private Fake(){
}
public static Fake getInstance(){
if(instance == null)
instance = new Fake();
return instance;
}
public String getTestString(String s){
return s;
}
}
I want to create a mock Fake object so I can mock method calls to non-static method getTestString(String s). I have used both Mockito and PowerMock (Mockito extension) in the way that comes below.
//using Mockito
Fake fake = Mockito.mock(Fake.class);
//using PowerMock
Fake fake = mock(Fake.class);
In both cases, as the code is attempting to mock a singleton (with a private constructor) I expect an exception to occur, but it just normally works. I suspect that there is something wrong with it and maybe it is not working actually.
Mocking doesn't instantiate a class, it creates a proxy for it. Having a private constructor or a constructor with parameters doesn't make a difference.
The behavior you're seeing is normal and expected.
By using mocking, it means you are not testing the class itself, but want to dictate the behavior of the class so that it performs in an arbitrary way you want.
The mock is only useful when you are trying to test some other class which has a dependency on the class being mocked.
In your case, if you want to test the class being a Singleton, you should test on an REAL instance rather than a mock of the class.
Moreover, your method:
public String getTestString(String s){
return s;
}
always returns the String you passed in, this does not look right to me and not sure what you are trying to do here.
Because you're not ever creating an actual instance of Fake, only an instance of a proxy that fulfills Fake's interface, the mock is succeeding.
Separately, regardless of whether Fake's constructor is private, Mockito cannot stub or verify static methods. If your real goal is to override getInstance, you'll need to do so with PowerMock.
However, by adjusting your system-under-test, you can skip Powermock and test your method with Mockito directly:
public class YourSystemUnderTest {
public int yourMethodUnderTest() {
return yourMethodUnderTest(Fake.getInstance());
}
/** Visible for testing. */
int yourMethodUnderTest(Fake fake) {
// ...
}
}
public class YourTest {
#Test
public void yourMethodShouldReturn42() {
Fake fake = mock(Fake.class);
YourSystemUnderTest systemUnderTest = new YourSystemUnderTest();
assertEquals(42, systemUnderTest.yourMethodUnderTest(fake));
}
}
It's even easier if YourSystemUnderTest takes a Fake instance in its constructor, because then you can set up the reference to the Fake instance once in a setUp() or #Before method.