How to test a class with a very complex constructor? - python-2.7

I have inherited some code which has some very complicated initialization in the constructor that depends on a very complex environment.
I only want to be able to test some functionality therefore just need an empty object, for example one which would have been generated by the default constructor, however the default constructor has been overwritten by some very complex stuff.
I do not have the ability to touch the source code therefore I just need the empty object to be able to call it's functions and test with.
How would I do this? I've looked at mocking but I can't seem to get the actual functionality of the class into the mock object.
UPDATE #1: Example to try to clarify what I'm asking
class Foo(object):
def __init__(self, lots_of_stuff):
lotsofthingsbeingdone()
class Bar(Foo):
def core_functionality(self, something):
val = does_something_important(something)
return val
I want to test core_functionality(). I want to feed it "something" and ensure that the val meets my expectation of what it should be.

Use this wisely. Don't make the legacy mess bigger:
# No constructors executed.
empty_object = object.__new__(YourClass)

Related

how to mock the objects that are instantiated inside a class but not inside any member functions

Suppose we have a class like this :-
class A {
internal val obj : Obj
get() = Application.getbean(Obj::class)
fun method1(){
val result = obj.somefunc()
..../code/
}
fun method2(){
...../code/
}
}
I wan't to write unit test using the junit mockito framework to test the functionality of method1 and wan't to mock obj object . In some other threads on stackoverflow people has suggested to use constructor dependency injected but that is not possible in my case because of the issue of circular dependency . In some other answers people has suggested to move this object instantiation inside the method ,but i don't want to go that way .Is there any way to mock this obj object.
It's very hard to unit test code, that is written in a non-testable way. That is why you should inject dependencies and not to hold them, that is why you should obtain objects and not to create them by yourself. If you're assume that your code might be tested, always think how first.
In your case it's a bit difficult to mock Obj, but not impossible since the actual creation (constructor calling) of the object is done with a different class (not the one being tested).
In your example you're using static method, maybe you can mock it's behavior with a PowerMockito? Please take a look at this answer.
Other than that, I just can suggest to change the code.
To inject object creating class as a dependency or use some other approaches, which might involve some architectural changes.

Can Mockito detect mock usage and field assignments?

This use case is perhaps best explained by the test:
#Test
public void testZeroInteraction() {
Pika pika = new Pika();
Trainer trainer=mock(Trainer.class);
pika.doNothing3(trainer);
verifyZeroInteractions(trainer);
}
This is my doNothing3() method in class Pika:
void doNothing3(Trainer trainerIn){
trainer=trainerIn;
trainerIn.name="Ash";
}
In this case, verifyZeroInteractions() does not complain and the test passes.
Can Mockito detect assignments as those in the doNothing3 method above?
If so, what Mockito method can be used?
OO is about behavior, not state.
Right the first paragraph in the Mockito documentation reads:
Let's verify some behaviour! ...
In that sense; when Mockito talks about interaction, what they (or any other mocking framework to my knowledge) mean is: method calls.
In other words: the mocked object knows nothing about the fields of the class it is mocking.
So, you could basically do the following:
keep your current testZeroInteraction() test (to prove that no methods are called)
add a second test, to check that a real input object doesn't change
Like:
#Test
public void testFieldUpdates() {
Pika pika = new Pika();
Trainer orig = new Trainer();
Trainer copy = new Trainer(orig);
pika.doNothing3(copy);
assertThat(orig, is(copy));
}
What this test "means": create a trainer object, and then create a copy of that. Pass the first object into your method; and afterwards check if that object still equals the copy.
But of course - that requires that you have some sort of "copy constructor"; and also a reasonable implementation of equals().
Finally: you should actually start by stepping back. My first sentence is: "OO is about behavior, not state". Translating to: the idea of having a Trainer class with public writeable fields is a design smell. You shouldn't do that. You don't create objects, pass them around and have other code directly write to fields. You call methods on other objects, you don't manipulate their state.
In other words: your approach violates a whole set of important OO principles. And because of that, Mockito is not supporting what you are doing. Because nobody should be doing what you are doing. So, as said: the real answer here is to fix your broken design.

UnitTesting help: using stub?

I have a question concerning unit testing.
I have to test a function, call it function A, that receives as input an instance of a class B, and returns true or false.
Now in my test I have to somehow create an object to pass to the function A; what I'm currently doing is to initialize the class B using its constructor and calling some of its methods to populate it, create the right structures, etc. and then pass it to the function A. Now, I'm not sure that this is a good pattern: in particular what happens if there's a bug in one the methods of class B, or I change its interface?
So I guess I would need to use a stub; but it seems weird to write a class that has basically the same structures of my class B; also the function A will ultimately work with the class B, so if I change the interface of class B then the test for function A should crash to tell me to change function A to accommodate the new interface.
What is the correct pattern to use?
NOTE: If you think this is primarily opinion based, please reformulate the question as: "According to the principles advocated in "The Art of Unit Testing", what would be the best thing to do here?" - for the rest of you who are sane, feel free to write an answer with a larger perspective
Edit
I should clarify, the sole purpose of function A is to take an instance of class B and verify that a certain condition is met. Now, I could create a stub in place of class B, but I am not sure this would make sense; it seems rather pointless. On the other hand to initialize B I do something like classB.addData(randomData); what happens if this code fails? I will get an error in the test for function A while the actual problem is in the initialization of class B
Edit 2
Some code that shows more explicitly what the function does. The real code is exactly the same, except the methods are more complicated but otherwise it's exactly the same
def functionA(objectB):
return objectB.data < 10
def testFunctionA():
objectB = classB()
objectB.addData(19) #Is this a problem or should I stub objectB?
assert(functionA(objectB) is False)
In my opinion, the most powerful tool in the unit testing toolbox is dependency injection, and that fits perfectly here.
When constructing an object, all its collaborator objects should be passed to its constructor in the form of interface references. In your case the unit to be tested is a function, but the principle is the same. The functions collaborator objects are passed to it in the same manner.
If your test object only collaborates with other objects through interfaces, it is possible to pass mock objects in unit testing. Also, frameworks like google mock makes it very convenient to create mocks, and write clean test cases where the expected interactions are easy to understand.
If this is what you meant, then yes, that is a good pattern.
Edit:
This is how i would write the test function.
def functionA(objectB):
return objectB.data < 10
def testFunctionA():
objectB = fakeClassB()
EXPECT_CALL(objectB, data).WillOnce(Return(19))
assert(functionA(objectB) is False)
Instead of passing a real classB object, pass a fakeClassB object. This makes the test depending on the interface of classB rather than the actual implementation of classB. A failing test is caused by a faulty use of the interface and not some implementation detail n classB. Depending on what language you are working with, this could be possible or not i suppose.
Another perk is build complexity. You can build the test function without building the implementation of classB. You only need to build the interface of classB and the fakeClassB.
There is a rule in testing: mock all units other than the tested one. The point of mocking is to provide some correct output values when you would call units that are used in the tested unit. You should explicitly provide some samples that you know are correct, so that the tested unit can not fail because of some fail caused of the unit used by it.
Too long for a comment:
in the scope of unit testing A, Bs implementation should not matter. Using a mock/stub/whatever in order to test the different branches of A is fine.
If Bs implementation at some point changes, that should not matter in regards to As implementation (in an ideal scenario, but your example is very abstract). If Bs implementation were to be significantly changed in so much that A is looking at different members of B, then yes, you could have an impact to As unit tests. If Bs implementation of arriving at the members that A relies on changes, that will not matter with a mocked version of B.
It will however matter to Bs unit tests.
If you have anything concrete I can elaborate, but right now it's mostly just an abstract answer for an abstract question.
def functionA(objectB):
return objectB.data < 10
def testFunctionA():
objectB = classB()
objectB.addData(19) #Is this a problem or should I stub objectB?
assert(functionA(objectB) is False)
is this python? I don't know python, but I'm guessing functionA returns true when objectB.data lt 10, and false otherwise.
Given all of that, functionA is still only returning a true or false based on a member of objectB. How objectB.data gets its data is not relevant to the scope of unit testing functionA, so objectB.data can and should (where possible) be mocked/stubbed in order to get a true unit test. Integration test is another story (you should use the real implementation for that, but your question was specific to unit testing)

TDD - Test if one method calls another

If method A's single role is to call method B, should I write a test that verifies method B is called when I call method A? Or is this a waste?
EDIT: I am editing to add some context. Here is my class:
module PaidGigs
class UserValue
def initialize(user)
#user = user
end
def default_bid(multiplier = 3.5)
PaidGigs::UserValue.cpm_value(#user.instagram_follower_count, multiplier)
end
def bid_value_including_markup(user_bid, multiplier = 3)
user_bid + PaidGigs::UserValue.cpm_value(#user.instagram_follower_count, multiplier, 0)
end
def self.cpm_value(base_count, multiplier, rounder = -1)
((base_count.to_f / 1000) * multiplier).round(rounder)
end
end
end
Should I write a test that verifies '#default_bid' calls '.cpm_value' with the proper arguments? Is this a waste of time, or is there value in this?
Don't test that one method within a method calls another. This will lead to a more fragile test, and create a barrier (although a small one) to refactoring. Your test should not care about the internals that produce the result, only that it's correct.
The answer changes if the method is delegating to another class - then you absolutely need to test, in a unit test, that the delegation occurs corectly by mocking the delegate.
There's value in methods that call others within the class: the name of the methods communicates the purpose of the method (if it's named well) and that's good for the human readers of your class. Well-named methods (and everything else) is hugely powerful, and largely underutilized. The names of low-level methods within a class can create a mini-DSL (Domain Specific Language) within the class, helping the reader to quickly understand what a high-level method is doing without taking the time to dig into the details.
What you're asking about is does it make sense to explicitly test everything your object does, or do you want to implicitly test it.
This is mostly a matter of opinion.
Personally, I see no value in writing that test, because eventually you should be writing a test that mocks out the return value of the method and verifying that function your testing actually mutates the mocked value in such a way. This way you implicitly test that you're calling the function - if you weren't using the method to get your end result, then the value would not align to your expected result.
Edit: A code example in something a bit more readable:
Calculator.cs
public class Calculator {
private IAddingService _addingService;
public Calculator(IAddingService addingService) {
_addingService = addingService;
}
public AddNumbers(int valueOne, int valueTwo) {
return _addingService(valueOne, valueTwo);
}
}
CalculatorTests.cs
public class CalculatorTests {
public void test_adding_numbers() {
var addingService = new Mock<IAddingService>()
addingService.Setup(service => service.Add(1,2)).Returns(2);
var calculator = new Calculator(addingService.Object);
var result = calculator.Add(1,2);
Assert.That(result, Is.EqualTo(2));
}
}
In this example, I've implicitly tested that adding service is the way that we add things because there's no action that allows calculator to determine this on its own.
I don't see why you wouldn't test it. It's easy to do and partially prevents further refactoring of this method to break something.

reusing business logic in a test class to save time

Just having a conversation with someone in the office about using a business logic class to build up some data in order to test another class.
Basically, he has class A which takes a complex type as a parameter and then generates a collection of a different complex type as a result. He's written tests around this class already. Now he's moved on to testing another class (class B) which takes the result of class A then performs some logic on it.
He's asked the question, "should I use class A to build up a scenario to test class B with".
At first I said yes as class A has tests around it. But then I figured well what if there's some bugs in class A that we haven't found yet... so I guess there must be a better way to address this scenario.
Does anyone have any thoughts on this? Is it OK to use existing logic to save time writing other tests?
Regards,
James
Stances on that might differ. Generally, if code is tested and you assume it works, you're free to use it. This is especially true when using already tested methods to help with testing others (within single class/unit). However, as this happens within single unit it's a bit different from your case.
Now, when dealing with 2 separate classes I'd say you should avoid such approach. Purely for the reason that those two classes might not be related in obvious way or their context/scope of usage might vastly differ. As in, somebody might change class A without even knowing class B exists. Class B tests suddenly break even though no changes were made to B code. This brings unnecessary confusion and is situation you usually don't want to find yourself in.
Instead, I suggest creating helper method within tested class B file. With stubs/fakes and tools like AutoFixture, you should be able to easily reproduce generation logic used by class A and have your own "copy" contained in class B tests.
In order to test class B, the result returned from the class A should be replicated somewhere in your test. If class A returns a list of persons, you will have an helper function in your test returning a fake List<Person> to use for your test.
Because you are only testing the class B, class A should not be used in your test.
NUnit provides a built in functionality in order to provide data for your tests, have a look to :
http://www.nunit.org/index.php?p=testCaseSource&r=2.5
Or you can simply create a DataFactory class with methods that returns the data (simple objects, collections etc..) you will consume in your tests.