Unit test on legacy code, object creation - unit-testing

I am adding unit tests to an existing application. The class relationship is like this:
class TopClass creates class A and B and common class AB;
class A creates class A1, A2, A3, A4 and AB;
class B creates class B1 and AB;
I am told to pass all depended objects (as interface) when creating the top level object in order to do dependency injection. So class Constructors need to be changed as this:
TopClass(A a, A1 a1, A2 a2, A3 a3, A4 a4, AB ab, B b, B1 b1)
A(A1 a1, A2 a2, A3 a3, A4 a4, AB ab)
B(B1 b1, AB ab)
Is it the right/good way? Is there a way that no need to create all objects at the beginning of the application?

No, that is not a good way.
If possible, you should only have to pass in interface A and interface B
TopClass(A a, B b)
This way unit tests for TopClass only worry about its direct dependencies and not dependencies of dependencies. This will also let you mock out implementations of A and B in your tests.
Then for tests of Ayou might have a constructor that passes in A1, A2 etc but TopClass shouldn't know about that.

Short answer: Yes, that's where you start, but it's not necessarily a good ending point. TopClass should care only about (interfaces of) A, B, and AB. The implementations and dependencies of those objects are not relevant to TopClass. This also means that mocking TopClass should be very simple: You need a mock A, a mock B, and a mock AB, and you can pass those in directly.
How do you create an A without caring about A's dependencies? Instead of an A instance, receive a Provider<A>, where Provider is Java's built-in no-argument factory interface.
At that point, your constructors look as follows:
TopClass(A a, B b, AB ab)
A(A1 a1, A2 a2, A3 a3, A4 a4, AB ab)
B(B1 b1, AB ab)
Where any of those types could be replaced with a Provider<Type> if you want to delay creation until you need it, or if you need more than one.
"But wait!" I hear you cry. "Doesn't that mean I have to make a complicated series of boilerplate Providers in order to hide the implementation/dependency details from TopClass?" Yes, it does, and you can do that manually--or you can use a dependency injection framework like Spring, Guice, or Dagger.
A manual one would look something like this:
public class EntryPoint() {
AB ab = new AB();
Provider<TopClass> provideTopClass() {
return new Provider<TopClass>() {
#Override public TopClass get() {
return new TopClass(provideA().get(), provideB().get(), provideAB().get());
}
};
}
Provider<A> provideA() {
return new Provider<AB>() {
#Override public AB get() {
return new A(provideA1().get(), provideA2.get(), ...);
}
};
}
Provider<AB> provideAB() {
return new Provider<AB>() {
#Override public AB get() {
return ab; // always reuse the same instance if you'd like
}
};
}
// and so forth
}
There, you've just extracted all of the creation and wiring into one class, which Guice can emulate at run-time and which Dagger can generate directly at compile-time. You'll need to work with your team to choose a framework you want, or start manually, but overall this should provide a lot of rewards in making an easy-to-assemble and easy-to-test application.

If you create the instances in this order:
AB ab = new AB();//and so on for all classes wihtout dependencies like a1, a2, ..., b1
A a = new A(a1, a2, a3, a4, ab)
B b = new B(b1, ab)
TopClass(a, b, ab)
But as you say, that TopClass creates instances of those classes, that is the actual problem. it should expect instances, not create them.
Maybe this way it doesn't even need the ab parameter if it only uses it for creating A and B.
Using some Dependency Injection Framework/Library can be one way of taking a lot of boilerplate away from the developer, but its costs like
efford for changing code to make it work in application and tests
runtime performance (depending on the framework)
should be considered.

Related

Sidecasting to other known superclass

I have a class inheriting from two other (Virtual) classes.
Let's call my two superclasses A and B. I can have objects that only inherit from A, objects that only inherit from B, and objects that inherit from both A and B.
Now, optimally, I'd like to have a container somewhere that holds objects known to inherit from both: Apologies for the C/Java syntax mashup, but this could look something like follows: std::vector<? : A, B>. Now, this doesn't exist, but as it turns out the class holding my container mainly uses the "A" functionality of those classes, which is why I'm currently using std::vector<A*>.
However, at one particular place somewhere else in my code, in a different place, that same vector gets accessed, but with the intention of using the "B" functionality.
While I personally know that I've made sure that all instances added to my vector extend from both A and B, the compiler does not. That makes it obviously difficult for me to access that B functionality.
So therefore, my question is as follows: How do I "sidecast" something from A to B? I have a pointer to A, with the dynamic type of something LIKE C (ie, inhereting from A and B - but not necessarily a SPECIFIC C), but want to get a pointer to B, obviously without changing the dynamic type.
dynamic_cast does the job, but I assume that's an ugly way of doing it. Any better ideas?
The way to do a sidecast is with a dynamic_cast. (You can even put this to the test. Head over to cppreference.com and search for "sidecast". There is exactly one hit.) The dynamic_cast will use its dynamic magic to ensure that the pointed-to object does in fact inherit from the new class (e.g. B) and dynamically determine what offset needs to be added to the pointer to perform the sidecast.
I would not call the dynamic_cast approach "ugly", but I do find it lacking in elegance. Acceptable, but not highly desired. I would prefer a more structured approach, given the assertion that the objects in question are known to inherit from both A and B. (If it weren't for this assertion, dynamic_cast would appear to be potentially the correct approach.)
You have a container somewhere that holds objects known to inherit from both A and B. Is there a name for such objects? If so, that could be the basis for a new class, call it AB, that inherits from A and B. It might do nothing other than inherit from those two classes, but that can still serve a useful role in your container. If your container were to hold pointers to AB, then the container would self-document that all elements must derive from both A and B. In addition, there would be no need to check types dynamically, nor to handle a failure to sidecast. The compiler would enforce that an object has to derive from both A and B to be added to the container in the first place. Furthermore, there would be no need to dynamically calculate an offset, as that offset gets baked into AB. The overall result is cleaner code with more checks made at compile-time. I would prefer this solution.
A comment from the OP makes the assertion that this proposed AB would "basically be completely empty and only serve as a wrapper, which is kind of ugly." I disagree with the "ugly" part, although I do not seek to argue that such an opinion is wrong. I will, though, point out that there is precedent. As far as the public interface goes, std::iostream is basically completely empty and only serves as a wrapper for std::istream combined with std::ostream. Its role is similar to what I propose for AB. You are welcome to consider std::iostream ugly, but it is undeniably standard.
There is no guarantee that the addresses of A and B in your objects will be the same, or even that the difference between these addresses will be the same for all C, D, E, F. This implies that you need to supply additional data for each element of the vector, which will tell how to get a pointer to base classes A and B.
dynamic_cast extracts this additional data from the virtual table (assuming that the compiler implements RTTI via the virtual table).
Pros:
No memory overhead.
Scalable, in case you want to add a third, fourth, etc base classes.
Cons:
Requires RTTI.
dynamic_cast can be somewhat slow (if it's implemented via traversing the class hierarchy).
Possible alternatives:
1. Adapter
class Adapter {
public:
template<class C>
/* implicit */ Adapter(C* pointer):
pointer_a_(pointer),
pointer_b_(pointer) {
static_assert(std::is_base_of_v<A, C> && std::is_base_of_v<B, C>,
"C should be derived from both A and B.");
}
A* getA() const { return pointer_a_; }
B* getB() const { return pointer_b_; }
private:
A* pointer_a_ = nullptr;
B* pointer_b_ = nullptr;
};
int main() {
std::vector<Adapter> my_vector;
C1 c1;
C2 c2;
my_vector.emplace_back(&c1);
my_vector.emplace_back(&c2);
for (Adapter& elem : my_vector) {
elem->getA()->foo();
elem->getB()->bar();
}
}
Pros:
Doesn't require RTTI.
Fast.
Can ensure at compile time that the objects in the vector are actually derived from both A and B.
Cons:
Memory overhead (per object) from the additional pointer.
2. Add a virtual function B* A::getB().
class A {
public:
// Return this (casted to B*), or nullptr if the dynamic object is not derived from B.
virtual B* getB() { return nullptr; }
// ...
};
class C : public FooWhichInheritsB, public A {
public:
B* getB() override { return this; }
};
int main() {
std::vector<A*> my_vector;
C1 c1;
C2 c2;
my_vector.emplace_back(&c1);
my_vector.emplace_back(&c2);
for (A* elem : my_vector) {
elem->foo();
elem->getB()->bar();
}
}
Pros:
Doesn't require RTTI.
No memory overhead (per object).
Calling the virtual function getB() is faster than performing dynamic_cast.
Cons:
Calling the virtual function getB() is slower than simply reading the pointer_b_ member in the Adapter implementation.
You need to remember to override getB() in each C, D, E, F, ...
3. Introduce a common base class AB
class AB : public A, public B {};
class C : public AB { /* ... */ };
class D : public AB { /* ... */ };
Pros:
Doesn't require RTTI.
No memory overhead (per object).
Even faster than Adapter.
Cons:
Adds a constraint on the class hierarchy - you can no longer add an object of the type class Foo : public A2, public B {}; (where A2 is derived from A) to the vector.

Assigning base part only from one object to another

I have simple inheritance when class B derives from A. A contains some members definition of simple types, no pointers. The B class is more complex and may contain pointers for some logic connections between objects. If I have two objects of type B (e.g. b1 and b2), how to write correctly the assignment when I am copying only A-part of b2 to b1.
The construction which works for me is: *(A*)&b1 = *(A*)&b2. But what is the correct way to implement this on the modern C++?
a) What you're doing looks technically correct (i.e. IMHO it should work everywhere)
b) However, as any code with casts, it is cumbersome and error-prone
c) To make it more readable, I'd suggest to add something like this:
class A {
//...
public:
void copyA(const A& other) {
*this = *other;
}
};
to your class A, then you'll be able to call much more obvious b1.copyA(b2) instead of your current (correct, but error-prone) code.

How to emit signal through a few class objects in Qt?

I have a few classes: Class A - highest class, Class B and Class C which are initialized in Class A constructor. In Class B constructor is initialized Class B1 and in Class C constructor is initialized Class C1. C1 object and B1 object does not see each other.
Every time I need to send signal from C1 class to B1 class, I connecting C1 and C, C and B, finally, B and B1. So every time my programm emitting a signal in C1 class object, it is sending to C class object then to B and then to B1. (On image) Is it a right Qt Way? Or there is a better way to do that?
You could add to class C an interface which returns C1 and a similar interface to class B, too. Then after creating classes C and B, class A could ask C1 and B1 and connect C1's signal to B1's slot.
Or, if you have lots of these kind of cases and you definitely don't want to expose classes C1 and B1 to A, you could create your own signaling mechanism. Some kind of "post office" where classes could register as receivers and to where classes could send messages. In this case, class B1 would register as a receiver and class C1 would send messages. C1 and B1 would know nothing about each other. The post office class would send C1's message to B1. This kind of "post office" class could also be implemented using Qt's signals and slots.

How to set a class or super class of oneself to an instance in C++

Title may sounds a little bit confusing, what I mean is that I have a class A that extends class B therefore have all the properties from B, and I want to set class B to an instance (with all the variables in B changed), so in this way B get's updated from somewhere else A will have corresponding effect whlie you can operate A and make their individual interaction. Code is as following.
class A : public B
{
public:
A() {}
~A() {}
void setA(B b)
{
// NOT SURE WHAT TO DO HERE
}
};
In java there is this and .super() and it doesn't seem to be the same in C++, this is a const and cannot be changed and I'm not sure how the .super() thing works.
BTW is that possible to see the class A itself to another instance of A?
Preface:
In Java if you write,
A a1 = new A();
A a2 = a1;
then a1 and a2 are referring to same object.
But in C++, the story is little different. You may not need new A() always to create an object.
Suppose you create an automatic object as below:
A a1; // a1 is created on stack
A a2 = a1; // a2 is created on stack and copied from a1
Note that a1 and a2 are different objects with same values. They are not referring to same entity. If you want a2 to be reference of a1 then write it as below:
A &a2 = a1;
If you want to simulate original Java behavior, then pointers are useful:
A *a1 = new A();
A *a2 = a1;
Answer:
By now, you will know the difference between C++ object and reference from above.
Having said that, C++ has better way to set an object rather than using setA(). You can simply overload the operator =
class A : public B
{
int member; // some member variable
public:
A& operator = (const A &a) // don't need to use `B&`
{
*(static_cast<B*>(this)) = a; // this calls `B::operator =`
this->member = a.member; // copy other members likewise
return *this;
}
};
Usage:
A a1, a2;
a1 = a2; // calls B::operator = and A::operator =
Also note that, you may not always need operator = to be defined inside the class. There are some special cases when you actually need it. By default compiler generates a copy constructor and assignment operator and performs the copying for you.
I figure that you only want to call setA(B b) only once, so that when b changes, A sees the latest value? If so, you are attempting to replace the sub-object, which is not possible.
For the use case you are attempting to achieve, it would be apt if B* were a member variable. Is there any reason why B has to be a base class of A?. It would be better if you give a concrete example with real names or explain in more detail.

Getting the pointer in C++ for a class that is part of another class with multiple inheritance

I have some classes that inherit from each other but they do so using templates. What I want is to effectively get a pointer and/or reference to one of the base classes as if it is one of the other possible derived classes dependant upon the templates
class a1
{
public:
int a;
virtual void func()
{
}
// other non virtual functions ...
};
class b1
{
public:
//no members or virtual functions
//other non virtual functions ...
};
class a2
{
public:
int a;
// ...
};
template < class T1 >
class derived : public T1,
public a2
{
int a;
// ...
};
Class derived can either inherit from class a1 or class b1, this is mostly to save space in derived as b1 is a blank class and so when derived is instanciated with template paramater b1 it is not carrying the extra load of the data members and virtual functions of a1.
However I now want to get a pointer or reference from derived(a1) that is really a pointer or reference for a type derived(b1).
What i'm really asking for is help on a "good" way of doing offsetof() but using inheritance where I can get the offsetof() a2, this I am assuming is a good pointer for derived(b1) because b1 is a blank class.
I have tried to get the pointer of derived(a1) object then add on the sizeof(a1) with the hopes that this will be the correct position but wanted to know if anyone else had suggestions of a better way.
As far as I understand you, you have e.g. a pointer to derived<a1>, and want a pointer to a1. Since a1 is a direct base class of derived<a1>, you can obtain this pointer by direct implicit casting:
derived<a1>* instance = whatever();
a1* pointer = instance;
It is however recommended that you make the cast explicit. Since this class is always safe and can be resolved at compile-time, use static_cast.
a1* pointer = static_cast<a1*>(instance);
Executive summary: Pointer arithmetics is something you should not do for traversing class hierarchies. There are static_cast and dynamic_cast available for exactly this purpose: They will warn you or error out when you try to do something dangerous, and generally have much more knowledge about the exact memory layout than you can ever have.
EDIT: You edited the question to say that you want to cast from derived<a1> to derived<b11>. This is not possible. static_cast and dynamic_cast do not support operations that change the memory layout of instances. Any pointer arithmetic is strongly advised against because you cannot know how the compiler arranges the data fields of instances in memory.
Have class b1 as the base class of class a1
If all you want to do is to save memory space for some of your objects then templates are probably not the best tool for that.
As b1 is empty derived<b1> adds nothing useful to a2, so why not using a simple inheritance class a1 : public a2 ? You can instantiate objects from either a1 or a2 depending if you need the additional data and they can all be casted to a2 (for example, if you want to store them in a list).
If you weren't using templates and just Multiple Inheritance, assuming that d is an instance of type Derived but is referenced as A1 you could have.
A1* a = new Derived();
Derived* d = (Derived*)a;
B2* b = d;
The template complicates things though.