📓 5.0.0.38 Testing A Private Field through its Getter and Setter Methods
In this lesson, we'll work on implementing the next simplest behavior for our Triangle logic, which is giving triangles a third side:
- We'll use the RGR workflow to test and create a private field called
_side3, which we'll access through the getter methodGetSide3()and the setter methodSetSide3(). - We'll treat the get and set actions of the private field as two distinct behaviors, so we'll run through the steps of the RGR workflow twice: first we'll implement the getter method, then afterwards we'll implement the setter method.
- When we write our tests, we'll use the organizational trick called "Arrange, Act, Assert" that we learned about in a previous lesson.
Reference for the "Red, Green, Refactor" (RGR) Workflow​
For reference, here's the "Red, Green, Refactor" (RGR) workflow we follow with TDD:
- Identify the simplest possible behavior the program must exhibit.
- Write a coded test for this behavior.
- Before coding, confirm the test fails.
- Implement the behavior with the least amount of code possible.
- Run the automated test to confirm it passes. If it doesn't, revisit step 4.
- Confirm all previous tests still pass. If it doesn't, revisit step 4.
- Check if code can be refactored. If so, refactor and repeat step 6.
- Commit your passing code.
- Repeat this process with the next simplest behavior.
Testing the Private Field _side3 through its Getter Method GetSide3()​
1. Identify the simplest possible behavior the program must exhibit.​
The next simplest behavior we'll tackle is creating a get action for the third side of a triangle. In terms of code, for our third side we'll create a private field called _side3, and we'll need to create a getter method called GetSide3() in order to access it.
2. Write a coded test for this behavior.​
Here's what the test will look like for our _side3 get action. Notice that we are invoking the GetSide3() getter method:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ShapeTracker.Models;
namespace ShapeTracker.Tests
{
[TestClass]
public class TriangleTests
{
... // 5 tests omitted for brevity
[TestMethod]
public void GetSide3_ReturnsSide3_Int()
{
// Arrange
int length3 = 55;
Triangle newTriangle = new Triangle(2, 3, length3);
// Act
int result = newTriangle.GetSide3();
// Assert
Assert.AreEqual(length3, result);
}
}
}
3. Before coding, confirm the test fails.​
If we run $ dotnet test in the ShapeTracker.Tests directory, we'll get two compiler errors which confirm that our test fails and there are no false positives in our code:
C:\Users\staff\Desktop\ShapeTracker.Solution\ShapeTracker.Tests\ModelTests\TriangleTests.cs(69,34): error CS1729: 'Triangle' does not contain a constructor that takes 3 arguments [C:\Users\staff\Desktop\ShapeTracker.Solution\ShapeTracker.Tests\ShapeTracker.Tests.csproj]
C:\Users\staff\Desktop\ShapeTracker.Solution\ShapeTracker.Tests\ModelTests\TriangleTests.cs(71,32): error CS1061: 'Triangle' does not contain a definition for 'GetSide3' and no accessible extension method 'GetSide3' accepting a first argument of type 'Triangle' could be found (are you missing a using directive or an assembly reference?) [C:\Users\staff\Desktop\ShapeTracker.Solution\ShapeTracker.Tests\ShapeTracker.Tests.csproj]
The first compiler error lets us know that our constructor can't take three arguments, even though we are using three arguments for our constructor in our new test.
The second compiler error lets us know that the GetSide3() instance method that we're invoking in our new test doesn't exist within the Triangle class. It asks us if we have forgotten to include a using directive, which implies that we have a GetSide3() method defined in another namespace; but that's not our issue.
4. Implement the behavior with the least amount of code possible.​
Let's add just enough code to get beyond the compiler errors. We'll update our code in the following ways:
- Create a private field called
_side3. - Add
length3as a parameter to our constructor and have it assigned as the value of our_side3field. - Create a public getter method called
GetSide3()that returns the_side3field.
namespace ShapeTracker.Models
{
public class Triangle
{
private int _side1;
public int Side1
{
get { return _side1; }
set { _side1 = value; }
}
public int Side2 { get; set; }
private int _side3;
public Triangle(int length1, int length2, int length3)
{
_side1 = length1;
Side2 = length2;
_side3 = length3;
}
public int GetSide3()
{
return _side3;
}
}
}