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).
Related
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))
I've got legacy code with some unit tests based on googlemock framework. While I was trying to extend the unit tests with some new scenarios I met the following problem:
class D
{
public:
void pubMethod1();
int pubMethod2();
// There are pretty much non-virtual methods, both public and private
...
protected:
uint method3();
void method4();
...
// Some class members are here
};
class SUT
{
public:
...
protected:
D _dep;
};
The SUT class (software under test) should be tested, its implementation is defined in file sut.cpp. The SUT depends on D class, whose implementation is in file d.cpp. To decrease linker dependencies I would not like to add d.cpp to the test, so there are many 'undefined symbol' errors against the D's members when I link the test. To eleminate the errors and provide predictable behaviour I'm going to create fake implementations for the D's methods in my test. However I'm still not able to use it with all the googlemock's power until the D's methods are virtual.
I like an idea to use WillOnce, AtLeast, WillRepeatedly, Invoke, etc. functions from the googlemock framework, because it makes unit test creation easier. The problem is that I don't like an idea to change the D's interface, turning its methods into virtual ones. Is it possible to use the googlemock functions with the fake implementations I'm going to create for the D's methods?
NOTE: I already considered the solution with templated SUT class, however I'm wondering if other solution exists.
First of all - the best would be to redesign your SUT class to have D injected via some abstract interface. Because the workaround I am describing below is really tricky - so not so easy to maintain and understand in future...
If you are going to make fake implememtation of your D class in UT target - then you can make Mock class for D: DMock. This DMock will not be related to D - not derived from it - but it needs to be paired with real/fake D objects.
So - see the example:
Create DMock - that imitates the D interface (note that you should mock only public functions - because your SUT uses only public ones):
class DMock
{
public:
MOCK_METHOD0(pubMethod1, void ());
MOCK_METHOD0(pubMethod2, int ());
};
Pair your real (but fake) D objects with DMock objects - something like this:
class DMockRepo
{
public:
// for UT
void addMockToUse(DMock* dMock) { freeMock.push_back(dMock); }
// for implementing D fake methods
DMock& getMock(D* original)
{
// TODO: use more sophisticated way to add mock to map...
if (not usedMock[original])
{
usedMock[original] = freeMock.front();
freeMock.pop_front();
}
return *useddMock[original];
}
static DMockRepo& getInstance() { return instance; } //singleton
private:
DMockRepo() {} // private
static DMockRepo instance;
std::map<D*,DMock*> usedMock;
std::deque<DMock*> freeMock;
};
Use mock to create fake implementation of public methods of D class:
void D::pubMethod1()
{
DMockRepo::getInstance().getMock(this).pubMethod1();
}
//
Non-public methods are irrelevant - so do whatever you like...
And use DMockRepo to set expectation on your D objects:
TEST(Usage,Example)
{
DMock dMock;
DMockRepo::getInstance().addMockToUse(&dMock);
SUT sut; // you should know how many D objects SUT needs - I assume just one
EXPECT_CALL(dMock, pubMethod1());
sut.doSomethingThatCallsDpubMethod1();
}
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.
I'm confused regarding inheritance when googletesting. I have a class A that has protected attributes. If I want to access those i have to extend that class, but at the same time i also need to extend public ::testing::Test for the sole purpose of gtest.
What is the most elegant solution to this problem?
Also I'm trying to avoid #define protected public
To avoid leaving traces of tests in the tested class use multiple-inheritance with a fixture:
class ToBeTested
{
protected:
bool SensitiveInternal(int p1, int p2); // Still needs testing
}
// Google-test:
class ToBeTestedFixture : public ToBeTested, public testing::Test
{
// Empty - bridge to protected members for unit-testing
}
TEST_F(ToBeTestedFixture, TestSensitive)
{
ASSERT_TRUE(SensitiveInternal(1, 1));
ASSERT_FALSE(SensitiveInternal(-1, -1));
}
There is a FRIEND_TEST declaration, which is used in the header of tested class. Basically it defines the test as a friend of the class. In my use case, we disable all test includes when compiling in RELEASE mode, so it doesn't do any harm the real executable.
Have a look at this
Is it possible to unit test a private class? I have something like
public class ClassA: ClassB
{
private class ClassX: ClassY
{
public static int TestMethod(int numberA, int numberB)
{
return numberA + numberB
}
}
}
I'd like to test the "TestMethod" but can't access it. I tried to create new instance for the private ClassX using Class A and Class Y but it won't let me access the "TestMethod"
It is not a good practice to test private members. They should be tested using pubic exposed members.
However, If you are using MSTest, You can use accessors.
If you are using other test frameworks, you can leverage reflection.
The above are applicable in .NET. I have no idea how to achieve the same in other languages (in case you are asking for java/other language).
There should be a public method somewhere that calls the method in your private class. You should unit test that method. If you can't get to your private method through a public interface, then there is probably no need for the private method to begin with.