Why database types aren't interface in GO - unit-testing

There is an emphasis on using interfaces instead of concrete types in order to make the code easier to test. I wonder though why this wasn't done for the types in the sql package like DB or Rows. In order to mock those dependencies I had to create my own interfaces so that I could write unit tests (not integration tests). Aren't DB facing code supposed to be tested that way?

Exposing interfaces in your public API instead of concrete types increases the risk of breaking other peoples code when you add methods to the interface.
See for example os.File. If os.File was an interface it would be an interface with 17 public methods. Adding an 18th method would break everyone who defined their own types that implemented the os.File interface. In contrast, adding an 18th method to the current os.File struct won't break any methods taking an io.Reader, io.Writer or any other interface that defines a subset of the methods of an os.File. It also won't break test code which mocks these io.Reader and io.Writer interfaces.
So expose an interface in your public API if you want other people to define their own implementations of them. Otherwise expose a concrete type and let people define their own interfaces implemented by your concrete type using only the subset of methods they need.

Related

Wanting to test private functions is a bad code smell?

When I find myself wanting to test the private functions of a class that has a small public API and a complex internal call structure I seem to end up choosing from the two following approaches:
If the class has functionality that is not reliant on the class'
state and would offer useful functionality to other potential client
code then I should break it out into a service and test it's public
API.
If the class has functionality that is reliant on class' state and
would be tightly coupled if broken out then I should test it through
the public API by passing the correct parameters and then name the
test so that it references the private function I am targeting.
I feel that testing private functions directly makes classes less easy to refactor and tests more brittle but testing private functions through the public API and binding them just by name and correct parameter values also feels a bit shoddy.
Is there a set of rules to abide by in these situations short of doing proper TDD? I have no choice as I am writing tests in retrospect.
You don't care about private methods being tested. You only care about the public API being tested. For a private method, all that matters about it is how it affects the visible behaviour of the object.
If you have some behaviour of your public API which is implemented as a private method, then that test will likely 'target' the private method through the arguments to the API method. That's not a BadThing per-se - it covers a genuine test case for a real behaviour of the public API. You might, at a later stage, decide to refactor your class in such a way that the same behaviour is implemented in some other fashion. What's important is that the test encapsulates the behaviour of the public API.
It may then happen that you extract the private method into its own class and the method becomes a part of the public API of the new class. That's fine too. Your new class becomes a dependency of the old one, and you can then use DI to decouple the intricacies of triggering the behaviour of the dependency from the actual test case. That too is good, provided the new class has a definite reason for existing beyond just servicing the first class.
It all boils down to what's the best thing for the code you're looking at - does it make sense to completely capture the behaviour of your original API without having to fiddle with mocked dependencies? In an ideal world this would probably always be the case, but as your API becomes larger or more complex or higher-level that can cause problems of its own.
The important thing to remember though is that your tests are never testing a private method. They're always testing a visible behaviour of the system under test, which may (or may not) be implemented in terms of one or more private methods.

Should I test the Interface and All objects that implement it

Hi
Assume I have an Interface A and a class B that implements A. Within my test class I create a dummy class that implements A and I "test the Interface methods" now my question is should I test the methods that class B "gets" from the interface.
In my experience, you just test concrete classes and their interaction with interfaces.
That is, if you have concrete class B that implements A, you just test B and its interaction with other objects it references.
Generally testing should touch all (executable) lines of code. If you are implementing an interface it makes it that much easier, since you can code tests that form the "contract" of the interface and now the tests apply to all implementors of the interface.
This ensures consistency across all implementors. Should you encounter a situation where implementors behave differently (e.g. NullReferenceException vs. ArgumentNullException) you can add tests specifying which is "right" and which is wrong. This leads to less surprises down the road.
I might even go as far as saying that every interface should have a set of tests attached to describe the expected behaviour.
There are of course implementation specific things that can only be tested on the concrete implementor (e.g. "Was the file written?" vs. "Was the record comitted?"). These things should be provided through overriding or lambdas to the interface's test suite.
yes, you should aim to get 100% code coverage with your testing
Since your interface shouldn't have any concrete implementation then you don't need to test it since there is nothing to test by definition. The testing should be for the concrete implementation of the interface.
If you find yourself in a situation where you need to have a partial implementaton of an interface you can do what I do. For instance, say I have a interface of an item. This I call IItem and has all the interface. Then I declare an Item which is the partial implementation of the interface for common code and then ItemA, ItemB, etc. for the specialisations of Item.
I read all your posts I I think this solution works best.
Interface A
{
String A1();
String A2();
}
public class B:A
{
String A1(){return "A1"}
String A2(){return "A2"}
}
public class testB
{
public void B_Can_Return_A1()
{
A b=new B();
Assert.True(b.A1=="A1")
}
}
But if you are removing a method from an interface that the concrete implementations still rely on surely you shouldn't be removing that part of the interface?
This is true but this should still be enforced in tests i.e. tested. interfaces (should) play a big role in development and changes may create huge problems down the line. If an object implements an interface I think this is how it should be tested or something similar.
Please comment on this.

Mocking non-virtual methods in C++ without editing production code?

I am a fairly new software developer currently working adding unit tests to an existing C++ project that started years ago. Due to a non-technical reason, I'm not allowed to modify any existing code. The base class of all my modules has a bunch of methods for Setting/Getting data and communicating with other modules.
Since I just want to unit testing each individual module, I want to be able to use canned values for all my inter-module communication methods. I.e. for a method Ping() which checks if another module is active, I want to have it return true or false based on what kind of test I'm doing. I've been looking into Google Test and Google Mock, and it does support mocking non-virtual methods. However the approach described (https://google.github.io/googletest/gmock_cook_book.html#MockingNonVirtualMethods) requires me to "templatize" the original methods to take in either real or mock objects. I can't go and templatize my methods in the base class due to the requirement mentioned earlier, so I need some other way of mocking these virtual methods
Basically, the methods I want to mock are in some base class, the modules I want to unit test and create mocks of are derived classes of that base class. There are intermediate modules in between my base Module class and the modules that I want to test.
I would appreciate any advise!
Thanks,
JW
EDIT: A more concrete examples
My base class is lets say rootModule, the module I want to test is leafModule. There is an intermediate module which inherits from rootModule, leafModule inherits from this intermediate module.
In my leafModule, I want to test the doStuff() method, which calls the non virtual GetStatus(moduleName) defined in the rootModule class. I need to somehow make GetStatus() to return a chosen canned value. Mocking is new to me, so is using mock objects even the right approach?
There are some different ways of replacing non-virtual functions. One is to re-declare them and compile a new test executable for each different set of non-virtual functions you'd like to test. That's hardly scaleable.
A second option is to make them virtual for test. Most compilers allow you to define something on the command-line so compile your code with -DTEST_VIRTUAL=virtual or -DTEST_VIRTUAL to make them either virtual or normal depending on whether or not it's under test or not.
A third option which may be usable is to use a mocking framework that lets you mock non-virtual functions. I'm the author of HippoMocks (disclaimer with regard to neutrality and so on) and we've recently added the ability to mock plain C functions on X86 platforms. This can be extended to non-virtual member functions with a bit of work and would be what you're looking for. Keep in mind that, if your compiler can see both the use and the definition of a function at one time that it may inline it and that the mocking may fail. That holds in particular for functions that are defined in headers.
If regular C function mocking is sufficient for you, you can use it as it is now.
I would write a Perl/Ruby/Python script to read in the original source tree and write out a mocked source tree in a different directory. You don't have to fully parse C++ in order to replace a function definition.
One approach would be to specify different sources for testing. Say your production target uses rootModule.h and rootModule.cpp. Use different sources for your testing target. You can specify a different header by changing your include path, so that #include "rootModule.h" actually loads unittest/rootModule.h. Then mock rootModule to your heart's content.

For me to use Moq, do all my classes have to implement an interface?

I want to use Moq, but I am using Nhibernate and I didn't create interfaces for all my Model classes (POCO classes).
Do I have to create an interface for each class for me to be able to moq my POCO classes?
You can mock virtual methods, but its best if you use an interface.
Reason I say this is as follows:
var mockObject = new Mock<IMyObject>();
If you use a virtual method it becomes:
var mockObject = new Mock<MyObject>(params...);
You are forced to include the parameters for concrete objects, but you obviously don't need to for interfaces. All tests using concrete classes will require updating if you decide to change the class' constructor at a later date. I've been burned by this in a past so try not to use virtual methods for testing anymore.
I should add that by attempting to mock concrete types you are defeating the purpose of mocking frameworks. You should be mocking roles, not types. Therefore working to an abstraction, in this case an interface is a great thing to do.
Another reason is how interfaces work, interfaces state a contract but not behavior. They should be used when you have multiple implementations, and I class testing as a behavior hence the valid reason to introduce a new interface.
The classes/methods you are Mocking either need to implement an interface or be virtual. You can test any class/method as long as its accessible, but there's no way to mock something that cannot be overridden or implemented explicitly.

How Do You Create Test Objects For Third Party Legacy Code

I have a code base where many of the classes I implement derive from classes that are provided by other divisions of my company. Working with these other devisions often have the working relationship as though they are third party middle ware vendors.
I'm trying to write test code without modifying these base classes. However, there are issues with creating meaningful test
objects due to the lack of interfaces:
//ACommonClass.h
#include "globalthermonuclearwar.h" //which contains deep #include dependencies...
#include "tictactoe.h" //...and need to exist at compile time to get into test...
class Something //which may or may not inherit from another class similar to this...
{
public:
virtual void fxn1(void); //which often calls into many other classes, similar to this
//...
int data1; //will be the only thing I can test against, but is often meaningless without fxn1 implemented
//...
};
I'd normally extract an interface and work from there, but as these are "Third Party", I can't commit these changes.
Currently, I've created a separate file that holds fake implementations for functions that are defined in the third-party supplied base class headers on a need to know basis, as has been described in the book "Working with Legacy Code".
My plan was to continue to use these definitions and provide alternative test implementations for each third party class that I needed:
//SomethingRequiredImplementations.cpp
#include "ACommonClass.h"
void CGlobalThermoNuclearWar::Simulate(void) {}; // fake this and all other required functions...
// fake implementations for otherwise undefined functions in globalthermonuclearwar.h's #include files...
void Something::fxn1(void) { data1 = blah(); } //test specific functionality.
But before I start doing that I was wondering if any one has tried providing actual objects on a code base similar to mine, which would allow creating new test specific classes to use in place of actual third-party classes.
Note all code bases in question are written in C++.
Mock objects are suitable for this kind of task. They allow you to simulate the existence of other components without needing them to be present. You simply define the expected input and output in your tests.
Google have a good mocking framework for C++.
I'm running into a very similar problem at the moment. I don't want to add a bunch of interfaces that are only there for the purpose of testing, so I can't use any of the existing mock object libraries. To get around this I do the same thing, creating a different file with fake implementations, and having my tests link the fake behaviour, and production code links the real behaviour.
What I wish I could do at this point, is take the internals of another mock framework, and use it inside my fake objects. It would look a little something like this:
Production.h
class ConcreteProductionClass { // regular everyday class
protected:
ConcreteProductionClass(); // I've found the 0 arg constructor useful
public:
void regularFunction(); // regular function that I want to mock
}
Mock.h
class MockProductionClass
: public ConcreteProductionClass
, public ClassThatLetsMeSetExpectations
{
friend class ConcreteProductionClass;
MockTypes membersNeededToSetExpectations;
public:
MockClass() : ConcreteProductionClass() {}
}
ConcreteProductionClass::regularFunction() {
membersNeededToSetExpectations.PassOrFailTheTest();
}
ProductionCode.cpp
void doSomething(ConcreteProductionClass c) {
c.regularFunction();
}
Test.cpp
TEST(myTest) {
MockProductionClass m;
m.SetExpectationsAndReturnValues();
doSomething(m);
ASSERT(m.verify());
}
The most painful part of all this is that the other mock frameworks are so close to this, but don't do it exactly, and the macros are so convoluted that it's not trivial to adapt them. I've begun looking into this on my spare time, but it's not moving along very quickly. Even if I got my method working the way I want, and had the expectation setting code in place, this method still has a couple drawbacks, one of them being that your build commands can get to be kind of long if you have to link against a lot of .o files rather than one .a, but that's manageable. It's also impossible to fall through to the default implementation, since we're not linking it. Anyway, I know this doesn't answer the question, or really even tell you anything you don't already know, but it shows how close the C++ community is to being able to mock classes that don't have a pure virtual interface.
You might want to consider mocking instead of faking as a potential solution. In some cases you may need to write wrapper classes that are mockable if the original classes aren't. I've done this with framework classes in C#/.Net, but not C++ so YMMV.
If I have a class that I need under test that derives from something I can't (or don't want to) run under test I'll:
Make a new logic-only class.
Move the code-i-wanna-test to the logic class.
Use an interface to talk back to the real class to interact with the base class and/or things I can't or won't put in the logic.
Define a test class using that same interface. This test class could have nothing but noops or fancy code that simulates the real classes.
If I have a class that I just need to use in testing, but using the real class is a problem (dependencies or unwanted behaviors):
I'll define a new interface that looks like all of the public methods I need to call.
I'll create a mock version of the object that supports that interface for testing.
I'll create another class that is constructed with a "real" version of that class. It also supports that interface. All interface calls a forwarded to the real object methods.
I'll only do this for methods I actually call - not ALL the public methods. I'll add to these classes as I write more tests.
For example, I wrap MFC's GDI classes like this to test Windows GDI drawing code. Templates can make some of this easier - but we often end up not doing that for various technical reasons (stuff with Windows DLL class exporting...).
I'm sure all this is in Feather's Working with Legacy Code book - and what I'm describing has actual terms. Just don't make me pull the book off the shelf...
One thing you did not indicate in your question is the reason why your classes derive from base classes from the other division. Is the relationship really a IS-A relationshiop ?
Unless your classes needs to be used by a framework, you could consider favoring delegation over inheritance. Then you can use dependency injection to provide your class with a mock of their class in the unit tests.
Otherwise, an idea would be to write a script to extract and create the interface your need from the header they provide, and integrate this to the compilation process so your unit test can ve checked in.