How to initialize test variables using Visual Studio CppUnitTestFramework - c++

I'm writing a roboter controller class Controller in which I'm using a struct Axis for each of the 4 controllable motors.
For each test I want to reset everything, so I created a pointer in the class which is changed to a new Controller before each test method. The initialisation works fine in TEST_METHOD_INITIALIZE, but once any TEST_METHOD is called the program seems reset the Axis pointers.
Thanks for your help!
Edit: After further analysis I have the theory, that the initialised Axis objects Axis init_mx are deleted after the method is finished.
Edit2: I think this a slightly more complex problem like this: Pointer to local variable in C++
Nevertheless, I didn't find a way to reset the Axis variables at for every method without actually resetting each variable in it.
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
...
namespace UnitTest
{
TEST_CLASS(UnitTestController)
{
public:
Controller* controller;
struct Axis *mx, *my, *mz, *mg;
TEST_METHOD_INITIALIZE(methodName)
{
Axis init_mx(50), init_my(50), init_mz(50), init_mg(5);
mx = &init_mx;
my = &init_my;
mz = &init_mz;
mg = &init_mg;
Controller init_controller(mx, my, mz, mg);
controller = &init_controller;
}
...
TEST_METHOD(id_3_next_mode)
{
mx->position = 5;
controller->getAxisPositionMx();
//Axis in pointers got reset and therefore have no pointers to the
//provided structs from TEST_METHOD_INITIALIZE
}
}
};
}
Controller.h(excerpt):
private:
struct Axis *mx, *my, *mz, *mg;
Controller.cpp (excerpt)
Controller::Controller(Axis *mx_in, Axis *my_in, Axis *mz_in, Axis *mg_in)
{
mx = mx_in;
my = my_in;
mz = mz_in;
mg = mg_in;
}

You found your original bug, but I think it's worth pointing out some details of how test modules, classes, methods, and the special initialize/cleanup methods are intended to work.
The most important thing to note is that a new instance of the class is instantiated every time a test method is executed, so each test will have a fresh set of class variables. This means that your example test class could look like:
TEST_CLASS(UnitTestController)
{
public:
struct Axis mx, my, mz, mg;
Controller controller;
// Define a constructor to initialize the class variables
UnitTestController() :
mx(50), my(50), mz(50), mg(50),
controller(mx, my, mz, mg)
{
}
TEST_METHOD(id_3_next_mode)
{
mx.position = 5;
controller.getAxisPositionMx();
}
};
If you wanted to have a variable persist between tests, you could put it outside the test class.
namespace UnitTest {
SomeClass moduleVar1;
TEST_CLASS(UnitTestClass)
{
public:
TEST_METHOD(TestMethod1)
{
Assert::IsTrue(moduleVar1.SomeMethod());
}
TEST_METHOD(TestMethod2)
{
Assert::IsFalse(moduleVar1.SomeOtherMethod());
}
};
}
The framework also provides the following Initialize and Cleanup functions which can be used to manipulate the test environment and fixtures:
TEST_METHOD_INITIALIZE - Called once before running each test method.
TEST_METHOD_CLEANUP - Called once after running each test method.
TEST_CLASS_INITIALIZE - Called once per module before running any tests belonging to this class.
TEST_CLASS_CLEANUP - Called once per module after running all tests belonging to this class.
TEST_MODULE_INITIALIZE - Called once per module before running any tests or class initalizers.
TEST_MODULE_CLEANUP - Called once per module after running all tests and class cleanups.

Related

Spock - How to work with repeated interactions

For few test cases I'm trying to follow a DRY principle, where only the interactions are different with same test case conditions. I'm not able to find a way to implement multiple methods in the interaction { } block.
As mentioned in http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_explicit_interaction_blocks, I'm using interaction { } in the then: block like below:
Java Code:
// legacy code (still running on EJB 1.0 framework, and no dependency injection involved)
// can't alter java code base
public voidGetData() {
DataService ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset() // happy path scenario; missing a null check
// other code
}
// other varieties of same code:
public voidGetData2() {
ItemEJB tmpItem = new ItemEJB();
ItemEJB item = tmpItem.findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
public voidGetData3() {
ItemEJB item = new ItemEJB().findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
Spock Test:
def "test scene1"() {
given: "a task"
// other code ommitted
DataService mockObj = Mock(DataService)
when: "take action"
// code omitted
then: "action response"
interaction {
verifyNoDataScenario() // How to add verifyErrorScenario() interaction to the list?
}
}
private verifyDataScenario() {
1 * mockObj.findByOffset(5) >> mockObj // the findByOffset() returns an object, so mapped to same mock instance
1 * mockObj.getOffset() >> 200
}
private verifyErrorScenario() {
1 * mockObj.findByOffset(5) >> null // the findByOffset() returns null
0 * mockObj.getOffset() >> 200 // this won't be executed, and should ie expected to throw NPE
}
The interaction closure doesn't accept more than one method call. I'm not sure if it's design limitation. I believe more can be done in the closure than just mentioning the method name. I also tried interpolating the mockObj as a variable and use data pipe / data table, but since it's referring the same mock instance, it's not working. I'll post that as a separate question.
I ended up repeating the test case twice just to invoke different interaction methods. Down the line I see more scenarios, and wanted to avoid copy & paste approach. Appreciate any pointers to achieve this.
Update:
Modified shared java code as the earlier DataService name was confusing.
As there's no DI involved, and I didn't find a way to mock method variables, so I mock them using PowerMockito, e.g. PowerMockito.whenNew(DataService.class).withNoArguments().thenReturn(mockObj)
Your application code looks very strange. Is the programming style in your legacy application really that bad? First a DataService object is created with a no-arguments constructor, just to be overwritten in the next step by calling a method on that instance which again returns a DataService object. What kind of programmer creates code like that? Or did you just make up some pseudo code which does not have much in common with your real application? Please explain.
As for your test code, it also does not make sense because you instantiate DataService mockObj as a local variable in your feature method (test method), which means that in your helper method mockObj cannot be accessed. So either you need to pass the object as a parameter to the helper methods or you need to make it a field in your test class.
Last, but not least, your local mock object is never injected into the class under test because, as I said in the first paragraph, the DataService object in getData() is also a local variable. Unless your application code is compeletely fake, there is no way to inject the mock because getData() does not have any method parameter and the DataService object is not a field which could be set via setter method or constructor. Thus, you can create as many mocks as you want, the application will never have any knowledge of them. So your stubbing findByOffset(long offset) (why don't you show the code of that method?) has no effect whatsoever.
Bottom line: Please provide an example reflecting the structure of your real code, both application and test code. The snippets you provide do not make any sense, unfortunately. I am trying to help, but like this I cannot.
Update:
In my comments I mentioned refactoring your legacy code for testability by adding a constructor, setter method or an overloaded getData method with an additional parameter. Here is an example of what I mean:
Dummy helper class:
package de.scrum_master.stackoverflow.q58470315;
public class DataService {
private long offset;
public DataService(long offset) {
this.offset = offset;
}
public DataService() {}
public DataService findByOffset(long offset) {
return new DataService(offset);
}
public long getOffset() {
return offset;
}
#Override
public String toString() {
return "DataService{" +
"offset=" + offset +
'}';
}
}
Subject under test:
Let me add a private DataService member with a setter in order to make the object injectable. I am also adding a check if the ds member has been injected or not. If not, the code will behave like before in production and create a new object by itself.
package de.scrum_master.stackoverflow.q58470315;
public class ToBeTestedWithInteractions {
private DataService ds;
public void setDataService(DataService ds) {
this.ds = ds;
}
// legacy code; can't alter
public void getData() {
if (ds == null)
ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset();
}
}
Spock test:
Now let us test both the normal and the error scenario. Actually I think you should break it down into two smaller feature methods, but as you seem to wish to test everything (IMO too much) in one method, you can also do that via two distinct pairs of when-then blocks. You do not need to explicitly declare any interaction blocks in order to do so.
package de.scrum_master.stackoverflow.q58470315
import spock.lang.Specification
class RepeatedInteractionsTest extends Specification {
def "test scene1"() {
given: "subject under test with injected mock"
ToBeTestedWithInteractions subjectUnderTest = new ToBeTestedWithInteractions()
DataService dataService = Mock()
subjectUnderTest.dataService = dataService
when: "getting data"
subjectUnderTest.getData()
then: "no error, normal return values"
noExceptionThrown()
1 * dataService.findByOffset(5) >> dataService
1 * dataService.getOffset() >> 200
when: "getting data"
subjectUnderTest.getData()
then: "NPE, only first method called"
thrown NullPointerException
1 * dataService.findByOffset(5) >> null
0 * dataService.getOffset()
}
}
Please also note that testing for exceptions thrown or not thrown adds value to the test, the interaction testing just checks internal legacy code behaviour, which has little to no value.

gmock Multiple mock instances, but only one is effective

I would like to test a class (Controller) that manages a set of entities of a certain kind. Entities are created internally in this class because a factory would be an overkill here, so here is how I inject mocks into it:
class TestController : public Controller {
public:
/* Mechanism for a mock injection */
std::shared_ptr<IEntity> create_entity() override {
return temp_entity;
}
/* Variable to hold the entity being injected */
std::shared_ptr<IEntity> temp_entity;
};
Production code invokes create_entity() in the Controller class, which I overload here, and adds the result to a container. temp_entity is the way I supply my mocks and the test, where I supply two distinct mock instances, looks like this:
class MockEntity : public IEntity {
MOCK_METHOD0(perform_operation, bool());
}
TEST(ControllerTest, TestFailure) {
std::shared_ptr<TestController> controller = std::make_shared<TestController>();
std::shared_ptr<MockEntity> entity1 = std::make_shared<MockEntity>();
controller->temp_entity = entity1;
controller->add_entity(); // This invokation fetches the result of create_entity()
std::shared_ptr<MockEntity> entity2 = std::make_shared<MockEntity>();
controller->temp_entity = entity2;
controller->add_entity(); // This invokation fetches the result of create_entity()
EXPECT_CALL(*entity1, perform_operation().WillOnce(::testing::Return(true));
EXPECT_CALL(*entity2, perform_operation().WillOnce(::testing::Return(false));
controller->run();
}
controller.run() only concurrently executes perform_operation() on each of the entities.
When the test is run, the function in the second expectation is called twice and the function in the first expectation is not run at all. I am sure that the controller operates on two distinct versions of an entity before executing run() function.
Is there a fundamental problem in what I am trying to do? How can I separate my expectations for these two mocks in a test? I tried creating two distinct mock classes with perform_operation() method being implemented in the mock body and when running the test in the debugger I still hit the method of one mock class twice.
The test looks correct and the way, how you inject the mocks into the system under test, is an absolutely reasonable method.
I suppose, the critical issue is in your class under Test. I rebuild your Test with the following controller:
class Controller {
public:
virtual std::shared_ptr<IEntity> create_entity() = 0;
void add_entity() {
auto entity = create_entity();
entities.push_back(entity);
}
void run() {
for(auto e : entities) {
bool i = e->perform_operation();
}
}
std::vector<std::shared_ptr<IEntity> > entities;
};
With this class the test succeeded like expected.

should we create object of any class on class level or function level

Which approach is better: I tried to find it on web, but I couldn't get a better answer.
1.
public class OtherClass
{
public int Add(int x, int y)
{
return x + y;
}
}
public class TestClass
{
OtherClass oClass = new OtherClass();
public int Fun1()
{
return oClass.Add(1,2);
}
public int Fun2()
{
return oClass.Add(1, 2);
}
}
2.
public class TestClass
{
public int Fun1()
{
OtherClass oClass = new OtherClass();
return oClass.Add(1, 2);
}
public int Fun2()
{
OtherClass oClass = new OtherClass();
return oClass.Add(1, 2);
}
}
I think it depends on what you are trying to test.
If you're testing the effects of a sequence of functions being executed on the same class instance then you might want to create a single instance (such as stress testing)
But otherwise I'd say it's always better to create a new instance of the class in each test function to ensure that the context of each test is predictable. If your test methods shared an instance of a class, and one test method fails and corrupts the state of the object under test, your subsequent test may fail for no other reason than the state of the object under test was corrupted by the previous failed test (it might appear the multiple tests are failing when in fact only one of the early ones is a true failure).
Depends on the scenario, if the class is gonna be shared on multiple functions and there are no specific arguments needed to create an instance of that class then it's better of being at the class level.
Let's say you're using the Fun1 and Fun2 often, having the instance creation on the method will have instance creation overhead rather than it being at the class level having a single instance, or better yet, make it static or make it singleton if you're sure that it's going to be a single instance throughout the whole app.
One benefit of having it in the class level is if you're doing unit testing, you can make an interface like IOtherClass and Inject it in the constructor of TestClass.
It would look something like this.
public class OtherClass : IOtherClass
{
public int Add(int x, int y)
{
return x + y;
}
}
public class TestClass
{
IOtherClass oClass;
public TestClass(IOtherClass _oClass)
{
oClass = _oClass;
}
public int Fun1()
{
return oClass.Add(1,2);
}
public int Fun2()
{
return oClass.Add(1, 2);
}
}
You're better off having it as a field in the class rather than declaring a new one in each method. The reason for this is simple, there won't be a line of code in each method declaring the variable meaning that if your declaration statement changes you will only have to change it in one place, not every method. Also it will make your code easier to read and add to because this line won't be duplicated everywhere.
Just remember if that field needs to be disposed your class should implement the IDisposable interface.

CoreDispatcher in a unit test with reactive extensions

I have the following bit of code in my Windows 8 Store app:
public static void ConvertUpdateStreamToCollection<T>(this IObservable<UpdateInfo<T>> input, ObservableCollection<T> list)
{
input
.ObserveOnDispatcher()
.Subscribe(upInfo => UpdateList(upInfo, list));
}
That ObserveOnDispatcher is there b.c. this will often be called on a background thread, and when it updates the observable list I will need it to be on the UI dispatcher. To first order this looks like it works fine when I run the app.
But I wish to test this with unit tests. I'm using the built in MSTest. The ObserveOnDispatcher throws, however, complaining there is no valid Window from which to get a CoreDispatcher.
I've seen work arounds for WPF in other places in Stack overflow. But that looks like just something to make the dispatcher run. This error seems more fundamental. Is there a known workaround?
(edit: better formatting now that I have a keyboard instead of a phone)
There's another way to achieve the same functionality:
.ObserveOnDispatcher()
Is fairly equivalent to:
.ObserveOn(new DispatcherScheduler(Dispatcher.CurrentDispatcher))
Now, instead of that DispatcherScheduler, have a class like:
public static class Schedulers
{
public static IScheduler Dispatcher {get; internal set;}
}
And change usage to:
.ObserveOn(Schedulers.Dispatcher)
Example:
void Main()
{
// For normal usage, we'll set this to the proper DispatcherScheduler
Schedulers.Dispatcher = new DispatcherScheduler(Dispatcher.CurrentDispatcher);
// Do stuff
new Thingy().DoStuff();
// for testing usage, we'll set this to be the immediate scheduler
Schedulers.Dispatcher = Scheduler.Immediate;
// Do stuff
new Thingy().DoStuff();
}
public class Thingy
{
public void DoStuff()
{
var query = Observable.Range(0, 10).ObserveOn(Schedulers.Dispatcher);
query.Subscribe(Console.WriteLine);
}
}

When using a mocking framework and MSPEC where do you set your stubs

I am relatively new to using MSpec and as I write more and more tests it becomes obvious to reduce duplication you often have to use a base class for your setup as per Rob Conery's article
I am happy with using the AssertWasCalled method to verify my expectations, but where do you set up a stub's return value, I find it useful to set the context in the base class injecting my dependencies but that (I think) means that I need to set my stubs up in the Because delegate which just feels wrong.
Is there a better approach I am missing?
The initialization/setup of stubs belongs to the arrange phase. The arrange phase is used to get the system into a known state before you exercise it.
In MSpec, the arrange phase is performed in Establish fields. For example:
public class When_the_temperature_threshold_is_reached
{
static ITemperatureSensor Sensor;
static Threshold Threshold;
Establish context = () =>
{
Sensor = MockRepository.GenerateStub<ITemperatureSensor>();
Sensor
.Stub(x => x.GetTemperature())
.Return(42);
Threshold = new Threshold(Sensor);
};
Because of = () => Reached = Threshold.IsReached(40);
It should_report_that_the_threshold_was_reached =
() => Reached.ShouldBeTrue();
}
When you write more tests using that kind of ITemperatureSensor, you should extract a base class that does complicated or repeated setup.
public abstract class TemperatureSpecs
{
protected static ITemperatureSensor CreateSensorAlwaysReporting(int temperature)
{
var sensor = MockRepository.GenerateStub<ITemperatureSensor>();
sensor
.Stub(x => x.GetTemperature())
.Return(temperature);
return sensor;
}
}
public class When_the_temperature_threshold_is_reached : TemperatureSpecs
{
// Everything else cut for brevity.
Establish context = () =>
{
Sensor = CreateSensorAlwaysReporting(42);
Threshold = new Threshold(Sensor);
};
}
This gives you the advantage that you can influence the stub's return value from the context itself: You do this by keeping as much information as possible local to the context and provide a good name for the "setup" method in the base class.
There is no need to specifiy or expect anything stub-related in Because. When Because is run, your system should be in a state where it can be exercised without further preparation.