SOLIDWORKS C# API - Test Create Line Method
Objective
I want to:
- Setup Test Model class for testing.
- Test Create Line Method.
- I will not explain each line, since they are already explained in previous articles.
- We will continue from previous article ๐ Setup Test Project.
Demo Video
Watch the video below to learn how to Test Create Line Method.
Please note that there are no explanation in the video.
Explanation of each step and why we write code this way is given in this post.
Modify [MainWindowViewModel]
First, we need to make method we want to test and members we going to use in our test class make as public.
- Public Member:
public string messageToShow;
- Public Method:
public bool CreateLine(SketchSegment sketchSegment, double x1, double y1, double z1, SldWorks.SldWorks swApp, SketchManager sketchManager, double x2, double y2, double z2)
- Modify Constructor:
- Remove Below lines.
StartPointViewModel.Header = "Start Point Co-ordinates";
EndPointViewModel.Header = "End Point Co-ordinates";
All these changes we need to do in our MainWindowViewModel class.
Add [Private Fields]
Then, we need to add some Private Fields.
These fields are shown below.
#region Private Fields
private readonly Mock<IUnitConversionHelper> _mockConversionHelper;
private readonly Mock<IEventAggregator> _mockEventAggregator;
private readonly Mock<IContainerProvider> _mockContainer;
private readonly Mock<IPointViewModel> _mockStartPoint;
private readonly Mock<IPointViewModel> _mockEndPoint;
private readonly Mock<SldWorks.SldWorks> _mockSwApp;
private readonly Mock<ModelDoc2> _mockSwDoc;
private readonly Mock<SketchManager> _mockSketchManager;
private readonly Mock<ModelDocExtension> _mockModelDocExtension;
private readonly Mock<SketchSegment> _mockSketchSegment;
private readonly MainWindowViewModel _viewModel;
#endregion
Please see below ๐๐ป image for reference.
In above code sample, we create a โPrivate Fieldsโ region.
Inside this region we create some Mock properties and a field for MainWindowViewModel class.
This viewmodel field will allow us to test different methods.
These Mock object will help us to mock the dependencies.
Understand Mock Object
In this section, I will explain a Mock object/field.
private readonly Mock<SldWorks.SldWorks> _mockSwApp;
- private: This means that only
MainWindowViewModelTestsclass can use it; no one else is allowed. - readonly: This means that once we set this field, we cannot change or replace it. We can only use it as it is.
Mock<SldWorks.SldWorks>: โMockโ refers to a simulated version ofSldWorks.SldWorks, designed to mimic its behavior without being the actual software.- _mockSwApp: This is the name we gave our variable.
Similarly, we can understand other Mock fields through same analogy.
Understand [MainWindowViewModel] Field
private readonly MainWindowViewModel _viewModel;
- private:
- This means that the
_viewModelcan only be accessed and used within theMainWindowViewModelTestsclass. - No other part of the program can see or change it.
- This means that the
- readonly:
- This indicates that once
_viewModelis set, it cannot be changed or reassigned to something else. - You can still use it, but you canโt replace it with a different
MainWindowViewModellater on.
- This indicates that once
- MainWindowViewModel:
- This is the type of the variable.
- It suggests that
_viewModelis a specific kind of object that contains the logic and data for the main window of an application.
- _viewModel:
- This is the name of the variable.
- The underscore at the beginning is a common convention in programming to indicate that this is a private variable.
Add [Constructor]
Now we need to add a Default Constructor and set up the Mock object fields.
In this section, we will:
- Create a region
- Make a Default Constructor
In this constructor, we will:
- Set up the mock object fields
We also use the Mock objects to set up our MainWindowViewModel field.
This will show us how we can use Mock objects to handle dependencies.
Please see below ๐๐ป code sample of Constructor.
#region Constructor
public MainWindowViewModelTests()
{
_mockConversionHelper = new Mock<IUnitConversionHelper>();
_mockEventAggregator = new Mock<IEventAggregator>();
_mockContainer = new Mock<IContainerProvider>();
_mockStartPoint = new Mock<IPointViewModel>();
_mockEndPoint = new Mock<IPointViewModel>();
_mockSwApp = new Mock<SldWorks.SldWorks>();
_mockSwDoc = new Mock<ModelDoc2>();
_mockSketchManager = new Mock<SketchManager>();
_mockModelDocExtension = new Mock<ModelDocExtension>();
_mockSketchSegment = new Mock<SketchSegment>();
_viewModel = new MainWindowViewModel(_mockEventAggregator.Object,
_mockContainer.Object, _mockConversionHelper.Object);
_viewModel.StartPointViewModel = _mockStartPoint.Object;
_viewModel.EndPointViewModel = _mockEndPoint.Object;
}
#endregion
Please see below ๐๐ป image for reference.
Set up Mock Fields
In the code below, we set up Mock type fields.
_mockConversionHelper = new Mock<IUnitConversionHelper>();
_mockEventAggregator = new Mock<IEventAggregator>();
_mockContainer = new Mock<IContainerProvider>();
_mockStartPoint = new Mock<IPointViewModel>();
_mockEndPoint = new Mock<IPointViewModel>();
_mockSwApp = new Mock<SldWorks.SldWorks>();
_mockSwDoc = new Mock<ModelDoc2>();
_mockSketchManager = new Mock<SketchManager>();
_mockModelDocExtension = new Mock<ModelDocExtension>();
_mockSketchSegment = new Mock<SketchSegment>();
Set up [MainWindowViewModel] Field
_viewModel = new MainWindowViewModel(_mockEventAggregator.Object,
_mockContainer.Object, _mockConversionHelper.Object);
ViewModel Initialization : In above code,
- A new instance of
MainWindowViewModelis created. - Dependencies injected into the constructor:
_mockEventAggregator.Object_mockContainer.Object_mockConversionHelper.Object
_mockEventAggregator.Objectrefers to an instance of a mock object created using a mocking framework. This resolve the dependency for creating instance.
_mockContainer.Objectis similar object, we use to resolve another dependency.
_mockConversionHelper.Objectis similar object, we use to resolve last dependency.
We need to resolve these dependencies otherwise we can not create the instance ofMainWindowViewModel.
_viewModel.StartPointViewModel = _mockStartPoint.Object;
_viewModel.EndPointViewModel = _mockEndPoint.Object;
ViewModel Property Assignments : In above code we set,
StartPointViewModelproperty of_viewModelvariable is assigned to_mockStartPoint.Objectmock object created using a mocking framework.EndPointViewModelproperty of_viewModelvariable is set to_mockEndPoint.Objectmock object created using a mocking framework.
Add Test Cases
Now we set up Test cases for below ๐๐ป CreateLine method of _viewModel variable.
public bool CreateLine(SketchSegment sketchSegment, double x1, double y1, double z1, SldWorks.SldWorks swApp, SketchManager swSketchManager, double x2, double y2, double z2)
{
sketchSegment = swSketchManager.CreateLine(x1, y1, z1, x2, y2, z2);
if (sketchSegment == null)
{
messageToShow = "Failed to Create Sketch line.";
swApp.CloseAllDocuments(true);
swApp.ExitApp();
return false;
}
return true;
}
To test CreateLine method, we need 2 test cases.
- TestCase 1 : When Line Creation Fails Returns False
- TestCase 2 : When Line Creation Succeeds Returns False
Before we add test cases, we will create a region called โTest Method [CreateLine]โ.
This will help organize our code properly.
Add [TestCase 1]
In this section, we set up TestCase 1.
Please see below ๐๐ป code sample for set up.
[Fact]
public void CreateLine_ReturnsFalse_WhenLineCreationFails()
{
// Arrange
SketchSegment sketchSegment = null;
_mockSketchManager.Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))
.Returns((SketchSegment)null);
// Act
bool result = _viewModel.CreateLine(sketchSegment, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0);
// Assert
Assert.False(result);
Assert.Equal("Failed to Create Sketch line.", _viewModel.messageToShow);
_mockSwApp.Verify(app => app.CloseAllDocuments(true), Times.Once);
_mockSwApp.Verify(app => app.ExitApp(), Times.Once);
}
Please see below ๐๐ป image for reference.
Explanation of above CreateLine_ReturnsFalse_WhenLineCreationFails is give below.
[Fact]
public void CreateLine_ReturnsFalse_WhenLineCreationFails()
{
}
[Fact]:- This is a test attribute.
- This attribute shows that this method is a test case that the
xUnittest runner recognizes.
public:- This means that the
CreateLine_ReturnsFalse_WhenLineCreationFailsmethod can be accessed from anywhere. - This is important, because
xUnittest runner is external agent. xUnittest runner need to have accessed to thisCreateLine_ReturnsFalse_WhenLineCreationFailsmethod.- Because of this requirment we need to give
publicaccessor.
- This means that the
void:- This is the return type of
CreateLine_ReturnsFalse_WhenLineCreationFailsmethod. - Generally we donโt return anything from test method.
- Because of this we return
voidmeans we are not returning anything.
- This is the return type of
CreateLine_ReturnsFalse_WhenLineCreationFails- This is the name of method.
- This name is created in 3 different parts and combined with underscore โ_โ.
- Different parts are explained below ๐๐ป:
- Part 1: Name of method we are testing.
- Part 2: Return value we are expecting.
- Part 3: Condition for which we are testing the method.
SketchSegment sketchSegment = null;
SketchSegment:- This is type of object we want to create.
sketchSegment:- This is name of object we want to create.
null:- This is the value we are assigning to
sketchSegmentvariable.
- This is the value we are assigning to
_mockSketchManager.Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))
.Returns((SketchSegment)null);
_mockSketchManager:- This is mocking object for
SketchManagerobject.
- This is mocking object for
_mockSketchManager.Setup():- We are using the
Setup()method from_mockSketchManagerobject. - This is important and most basic one you should learn.
- This
Setup()method allow us to setup the behavior of object it is mocking and its members/methods.- Please follow me and you will be able to understand how we setup the child members/methods.
- We are using the
Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))smis object we are mocking.smrepresentSketchManager.- From this
smobject we will setupCreateLinemethod. - This method takes 6 double parameters.
- We are defining that all 6 parameters will take any double value.
Returns((SketchSegment)null)- Here are setting up return value of
CreateLinemethod. - Above we are saying, whenever
CreateLinemethod called, returnnull. - Since
CreateLinemethod returnSketchSegmenttype hence we need to cast this also while setting up return value.
- Here are setting up return value of
// Act
bool result = _viewModel.CreateLine(sketchSegment, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0);
In above code, we are calling CreateLine method of _viewModel variable and store the return value into result variable.
_viewModel:- ViewModel variable whose method we want to test.
CreateLine:- Method we want to test.
CreateLine(sketchSegment, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0)- Calling
CreateLinemethod and passing parameters to method. sketchSegment: Previously created variable.0, 0, 0:X1, Y1, Z1co-ordinate of start point._mockSwApp.Object:SldWorksobject from_mockSwAppvariable._mockSketchManager.Object:SketchManagerobject from_mockSketchManagervariable.10, 10, 0:X2, Y2, Z2co-ordinate of end point.
- Calling
// Assert
Assert.False(result);
Assert.Equal("Failed to Create Sketch line.", _viewModel.messageToShow);
_mockSwApp.Verify(app => app.CloseAllDocuments(true), Times.Once);
_mockSwApp.Verify(app => app.ExitApp(), Times.Once);
Assert.False(result);:- We are checking value of
resultvariable isfalse. - If return value is
falsethen our asseertion is true.
- We are checking value of
Assert.Equal("Failed to Create Sketch line.", _viewModel.messageToShow);- Similar to previous line, here we are checking value of
_viewModel.messageToShowis equal to Failed to Create Sketch line. - If both value are same then our asseertion is true.
- Similar to previous line, here we are checking value of
_mockSwApp.Verify(app => app.CloseAllDocuments(true), Times.Once);:- Here we are verifying
CloseAllDocuments()method is called 1 time only. - We need to do this to make sure our code did not run too much.
- Here we are verifying
_mockSwApp.Verify(app => app.ExitApp(), Times.Once);:- Here we are verifying
ExitApp()method is called 1 time only. - We need to do this to make sure our code did not run too much.
- Here we are verifying
Add [TestCase 2]
In this section, we set up TestCase 2.
Please see below ๐๐ป code sample for set up.
[Fact]
public void CreateLine_ReturnsTrue_WhenLineCreationSucceeds()
{
// Arrange
_mockSketchManager.Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))
.Returns(_mockSketchSegment.Object);
// Act
bool result = _viewModel.CreateLine(null, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0);
// Assert
Assert.True(result);
_mockSwApp.Verify(app => app.CloseAllDocuments(It.IsAny<bool>()), Times.Never);
_mockSwApp.Verify(app => app.ExitApp(), Times.Never);
}
Please see below ๐๐ป image for reference.
Explanation of above CreateLine_ReturnsTrue_WhenLineCreationSucceeds is give below.
[Fact]
public void CreateLine_ReturnsTrue_WhenLineCreationSucceeds()
{
}
[Fact]:- This is a test attribute.
- This attribute shows that this method is a test case that the
xUnittest runner recognizes.
public:- This means that the
CreateLine_ReturnsTrue_WhenLineCreationSucceedsmethod can be accessed from anywhere. - This is important, because
xUnittest runner is external agent. xUnittest runner need to have accessed to thisCreateLine_ReturnsTrue_WhenLineCreationSucceedsmethod.- Because of this requirment we need to give
publicaccessor.
- This means that the
void:- This is the return type of
CreateLine_ReturnsTrue_WhenLineCreationSucceedsmethod. - Generally we donโt return anything from test method.
- Because of this we return
voidmeans we are not returning anything.
- This is the return type of
CreateLine_ReturnsTrue_WhenLineCreationSucceeds- This is the name of method.
- This name is created in 3 different parts and combined with underscore โ_โ.
- Different parts are explained below ๐๐ป:
- Part 1: Name of method we are testing.
- Part 2: Return value we are expecting.
- Part 3: Condition for which we are testing the method.
// Arrange
_mockSketchManager.Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))
.Returns(_mockSketchSegment.Object);
_mockSketchManager:- This is mocking object for
SketchManagerobject.
- This is mocking object for
_mockSketchManager.Setup():- We are using the
Setup()method from_mockSketchManagerobject. - This is important and most basic one you should learn.
- This
Setup()method allow us to setup the behavior of object it is mocking and its members/methods.- Please follow me and you will be able to understand how we setup the child members/methods.
- We are using the
Setup(sm => sm.CreateLine(It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>(), It.IsAny<double>()))smis object we are mocking.smrepresentSketchManager.- From this
smobject we will setupCreateLinemethod. - This method takes 6 double parameters.
- We are defining that all 6 parameters will take any double value.
Returns(_mockSketchSegment.Object)- Here are setting up return value of
CreateLinemethod. - Above we are saying, whenever
CreateLinemethod called, returnSketchSegmentobject from_mockSketchSegment.Objectvariable.
- Here are setting up return value of
// Act
bool result = _viewModel.CreateLine(null, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0);
In above code, we are calling CreateLine method of _viewModel variable and store the return value into result variable.
_viewModel:- ViewModel variable whose method we want to test.
CreateLine:- Method we want to test.
CreateLine(null, 0, 0, 0, _mockSwApp.Object, _mockSketchManager.Object, 10, 10, 0)- Calling
CreateLinemethod and passing parameters to method. null: We are passingnullvalue forSketchSegmentparameter.0, 0, 0:X1, Y1, Z1co-ordinate of start point._mockSwApp.Object:SldWorksobject from_mockSwAppvariable._mockSketchManager.Object:SketchManagerobject from_mockSketchManagervariable.10, 10, 0:X2, Y2, Z2co-ordinate of end point.
- Calling
// Assert
Assert.True(result);
_mockSwApp.Verify(app => app.CloseAllDocuments(It.IsAny<bool>()), Times.Never);
_mockSwApp.Verify(app => app.ExitApp(), Times.Never);
Assert.True(result);:- We are checking value of
resultvariable isTrue. - If return value is
Truethen our asseertion is true.
- We are checking value of
_mockSwApp.Verify(app => app.CloseAllDocuments(true), Times.Never);:- Here we are verifying
CloseAllDocuments()method Never called. - In our test method, we define that if we successully create
SketchSegmentobject, then thisCloseAllDocuments()will not be called.
- Here we are verifying
_mockSwApp.Verify(app => app.ExitApp(), Times.Never);:- Here we are verifying
ExitApp()method Never called. - In our test method, we define that if we successully create
SketchSegmentobject, then thisExitApp()will not be called.
- Here we are verifying
##
Before running test cases, we need to rebuild the Test project.
After rebuild, we see test cases in Test Explorer as shown in below ๐๐ป image.
Now we run all test cases.
Please see below ๐๐ป image for reference.
This is it !!!
I hope my efforts will helpful to someone!
If you found anything to add or update, please let me know on my e-mail.
Hope this post helps you to Test Create Line Method.
If you like the post then please share it with your friends also.
Do let me know by you like this post or not!
Till then, Happy learning!!!





