MSTest

MSTest is a product built into Visual Studio.

The idea is you break testing down into little pieces that test different parts of your application. Then have MSTest test all those pieces.

An MS Test project contains a series of class files. There’s an initialize test section per class file, and then a series of functions which you write to perform tests.

In my case I setup class per business object, and then a method for each method in the business object class.

standard patterns

A test class may have a stage/tear down process.

Each testing method might have 3 sections: the commonly referred to as Arrange / Act / Assert. (For me the pattern is good, but the terms are bad. I tend to thing something along the line of setup test / perform the test / analyse results.)

Sample

Here is a sample of a test class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
namespace Notes.API.Tests
{
\[TestClass\]
public class NoteControllerTests
{
private NoteController _controller;
private Mock<INoteService> _mockNoteService;

\[TestInitialize\]
public void Setup()
{
// Arrange

// here is some sample data
var noteDtoList = new List<NoteDto>
{
new NoteDto { ApplicationKey = "MyApp",
ApplicationSubKey = "Notes",
CompanyKey = "Test",
Note = "This is a new note - 1",
Who = "John Doe" },
new NoteDto { ApplicationKey = "MyApp",
ApplicationSubKey = "Notes",
CompanyKey = "Test",
Note = "This is a new note 2",
Who = "John Doe" },
// Add more NoteDto instances as needed
};

result.WasSuccessful = true;

// here is a mock object - a service mock
_mockNoteService = new Mock<INoteService>();

// you would add a .setup ().returnAsync() per function you are emulating
_mockNoteService
.Setup(service => service.GetAllNotesAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(result);

// this command creates your API class, with a fake service layer.
_controller = new NoteController(_mockNoteService.Object);

}


\[TestMethod\]
public async Task T005_GetNotes_ReturnsOkResult()
{
// Arrange
string companyKey = "0";
string applicationKey = "0";
string applicationSubKey = "0";

// Act
// this calls the API, and returns information in an aTaskActionResult object. that object will be studied.
IActionResult aTaskActionResult = await _controller.GetNotes(companyKey, applicationKey, applicationSubKey);

// Assert
// here is our test cases

// an Assert function performs a test. In our case we want to make sure we got ack an OkObjectResult type of object
Assert.IsInstanceOfType(aTaskActionResult,
typeof(OkObjectResult),
"1. Not an OkObjectResult. What you have is a " + aTaskActionResult.GetType());

//
// Assert Statements are tests.
// If the test passes move on to the next statement.
// If the test fails then send a message to MS Test.
// Then MSTest will exit this method and start testing the following method.
//


// if we did return an OkObjectResult, then we'll instantiate the object as an OkObjectResult
var okResult = (OkObjectResult)aTaskActionResult;

// and then pull the model out of that object (which incidenttly is a baseResult object with a list of note objects)
IResult<List<NoteDto>> aModel
= (IResult<List<NoteDto>>)okResult.Value; // This will give you the model object

// we'll test that class to make sure it is what we think it is.
Assert.IsInstanceOfType(aModel,
typeof(IResult<List<NoteDto>>),
"2. Not a <IResult<List<NoteDto>>> it's a " + okResult.Value.GetType());

// the testing goes on and on.
var resultValue = (IResult<List<NoteDto>>)okResult.Value;

Assert.IsTrue(resultValue.WasSuccessful,
"3. resultValue.WasSuccessful was not True");

// Add additional assertions based on the expected result
}

//
// after this test is coded, then we create another test for another API
// method that should be tested.
//
\[TestMethod\]
public async Task T010_GetNote_ValidInput_ReturnsOkResult()
{
}

// and so on
\[TestMethod\]
public async Task T015_CreateNote_ValidInput_ReturnsOkResult()
{
}
}
}

Opinions

Today (May 16, 2024) I am a MSTest rookie. I’ve noticed a few things which could be problems with me, or problems with the program that could be fixed the day after I publish this paper.

  • Debug doesn’t work, so I cannot pause the test and study results. This forces me to add messages to each assert statement to better track down where it fails in code. - bad.
  • Sometimes the code fails, not in an assert statement but outsie that, in which case I do not know of a nicer way to get a message to the MS Test UI. - bad.
  • As I am developing the test case / and similtaneously debugging my API, if I rerun a test (without saving my code changes), it will save the code changes, recompile, and run the latest version of that code - good.