Hello all,
Not sure if this is the best place to ask, so I would appreciate any info or suggestions on this.
Background Info:
I created an mdlapp in C++ that allows a user to click on an element and display an arrow showing the its orientation (using the orientation property from the ISM schema). I now want to write unit tests to test and verify that my getOrientation() method works as expected. This is because the orientation of an element in the ISM schema is represented as an IGeometry struct and needs to be processed in order to get the actual DPoint3d value representing its orientation.
My problem:
I am trying out the testing framework Catch2 (https://github.com/catchorg/Catch2) and am using it to write unit tests for my mdlapp. I want to have these tests run during a build of my mdlapp so that I can always verify my code. My problem is that I'm having trouble trying to set up some mocked or fake objects/data so that I can test my methods and was wondering what's the best way to go about this?
Here's an example of a test in Catch2 (hopefully it's easy to understand):
TEST_CASE("Should return orientation vector of (0, 0, 0) when there is no EC instance data (nullptr)") { // arrange DPoint3d expectedOrientation; expectedOrientation.Zero(); // act // method will return orienation of (0,0,0) if first parameter is null DPoint3d testOrientation = SmcApi::getOrientationOfElement(nullptr, L"Orientation"); // assert REQUIRE( expectedOrientation.x == testOrientation.x ); REQUIRE( expectedOrientation.y == testOrientation.y ); REQUIRE( expectedOrientation.z == testOrientation.z ); }
This is my getOrientation method which isn't set in stone as I'm open to changing things in order to get it to work:
DPoint3d MyApiClass::getOrientationOfElement(DgnECInstancePtr instance, WCharCP propertyAccessString) { DPoint3d orientationVector; orientationVector.Zero(); ECValue value; ECValueR valueR = value; if (instance != nullptr && SUCCESS == instance->GetValue(valueR, propertyAccessString)) { // Get the IGeometry object of the Orientation property IGeometryPtr testGetGeo = valueR.GetIGeometry(); // If the geometry is a CurvePrimitive if (testGetGeo != NULL && testGetGeo->GetGeometryType() == IGeometry::GeometryType::CurvePrimitive) { // Since it is a CurvePrimitive, get the CurvePrimitive ICurvePrimitivePtr testCurvePrim = testGetGeo->GetAsICurvePrimitive(); Bentley::ICurvePrimitive::CurvePrimitiveType testCurvePrimType = testCurvePrim->GetCurvePrimitiveType(); // If the CurvePrimitive is a Line CurvePrimitive if (testCurvePrimType == ICurvePrimitive::CurvePrimitiveType::CURVE_PRIMITIVE_TYPE_Line) { // Get the line segment of the Line CurvePrimitive DSegment3dCP testSegment = testCurvePrim->GetLineCP(); // Get the start and end points DPoint3d start, end; testSegment->GetStartPoint(start); testSegment->GetEndPoint(end); if (start == end) { // Get the orientation vector by normalizing it orientationVector.Normalize(start); } else { // Was trying to extend this method for other properties // can ignore this within the context of my question orientationVector = start; } } } } return orientationVector; }
Some things I tried:
- That first test case is very simple since I'm just passing in nullptr but now I'm trying to setup my own data with DPoint3d orientations so that I can test my method. In my getOrientationOfElement() method, I pass in a DgnEcInstancePtr and tried to create one from scratch in one of my unit tests but when trying to compile/run it, this fails because of a segmentation fault.
- I tried to 'create" a DgnFile and loading an existing one following the Microstation API documentation but this also fails with a seg fault. I think this code snippet seg faults at the very first line when trying to create the DgnDocumentPtr as I tried compiling and running it with all the other lines commented out:
DgnDocumentPtr dgnDoc = DgnDocument::CreateForLocalFile(L"path\\to\\my\\file.dgn"); DgnFilePtr dgnFilePtr = DgnFile::Create(*dgnDoc, DgnFileOpenMode::ReadOnly); //Load the DGN file DgnFileStatus dgnFileStatus = dgnFilePtr->LoadDgnFile(&openForWriteStatus);
Questions:
- Is it possible to access the Microstation API like this without running API? I guess I'm just wondering if it's possible to create the data/objects I need so that I can run my tests during my build of the mdlapp.
- If yes, I would appreciate any info on what I should be trying
- If no, does this mean I need to have MicroStation running in order to get this to work?
- Would it be possible to run MicroStation in the background or anything since I'm trying to run these unit tests as part of a build?
Thanks for taking the time to read all of this. Again, any info on this is greatly appreciated. Thank you!