Number(s) -> Attribute of the Calculation, * 2 so this is either an array or 2 properties. Decided on 2 properties. Also Class by Input (Architectural Requirement)
ExpectedResult -> Attribute of the Calculation, same type as Number so Class by Input (Architectural Requirement)
Right -> Attribute of the calculation, rename to IsCorrect
File -> Class due to Calculations and Store, Equivalent to student record, rename to Student
Calculations -> Attribute of File, indicator of many indicates an array of Calculation
Calculation -> Class storing relationship between numbers and results and Calculate
User -> Actor
System -> equivalent to the entire app ignore
Input -> Class due to Valid and Enter (Architectural Requirement) used by Number
Valid -> Property of Input (Architectural Requirement)
Verbs
Enter -> Action on Number to receive input from the user, Number being of Input makes this action on Input (Architectural Requirement)
Calculate -> Action on Calculation, runs the math.
Store -> Action on Calculations (so in File/Student), equivalent to Add on a List (EDIT NOTE: Missing on the diagram)
Correct -> Action by the user equivalent to calling Enter again so dropped
By implement I don’t mean write a user interface, I want the classes created as designed then I want you to try to add the functionality where it should go.
This assignment will assume you’re using TDD as described here:
If you have a diagram to work with, the design portion has already been completed and you can simply follow the direction provided only solving roadblocks when you find something missing.
When creating a new Unit Test first. It can help to add 3 comments initially.
// 1. The variables I have
// 2. The action being tested
// 3. The asserts that confirm it worked.
Once done these comments can be removed.
When writing your test you start at 1., then 3., then you code 2. To make it pass. This document will use this format. Names in braces {} are considered variable to change to your situation.
On the diagram there are classes you can construct and classes you can’t. You may recall that an abstract class cannot be constructed. Once you have this figured out you can proceed with construction.
You create a unit test class to test the construction of a class and create the class separately as well. So, you now have 2 files. One a unit test with code creating the object and asserting it is not null, and one a class declaration with nothing in it. You repeat this with every class that can be constructed.
Construction test. Can you build an object in memory?
Unit test Class {ClassName}ConstructionTest
Unit test Method {ClassName}Construction
//1. A variable defined of type {ClassName} You will need to create the class file now to remove the syntax error
//3. Assert.IsNotNull() on the variable
//2. Construct the class and put it in the variable.
Once you’ve created every constructible class on the diagram, you should have a class file and unit test for every class, you can move on to Attributes and Relationships. Work with attributes in Inherited classes as though they are in this class. You will create a unit test class for every single attribute, but should be generating code for the attributes inside the class files you created in construction
Attribute Tests. Can your object access the data it needs?
Unit test Class {ClassName}Has{Attribute}Test
Unit test Method {ClassName}Has{Attribute}
//1. A variable defined of type {ClassName} and now with the code to construct it as well. A test value variable matching the type of the attribute. Remember if there is a relationship on the diagram the type IS that other class.
//3. Assert.IsNotNull() on the variable, can keep this here to make sure your setup is correct. Use Assert.AreEqual to compare your testVariable with what is in {ClassName}.{Attribute}
//2. Assign a value to {ClassName}.{Attribute}
Once you’ve created every attribute your class should have access to what it needs to perform actions. Work with methods in inherited classes as though they are in this class. You will create a unit test class for every single action but should be generating code for the attributes inside the class files you created in construction. You will also need to account for both Invalid attribute and parameter data as well as alternate branches in the method, so actions generate a lot of unit tests.
Since the main objects require dependent data to be setup already it makes sense to start at the lowest level constructible object first.
Valid Method Tests. Can your object perform the actions it should?
Unit test Class {ClassName}{Action}Test
Unit test Method {ClassName}{Action}
//1. A variable defined of type {ClassName} and now with the code to construct it as well and the code to construct or fill every attribute. Test variable(s) containing the expected result state values of the object. If the action should return a value itself (it’s not setting attributes) then you also need a test variable to store the result of the action. If the action is dependent on data that IS NOT an attribute you would set that up here as well to pass as a parameter.
//3. Assert.IsNotNull() on the variable, can keep this here to make sure your setup is correct. Use Assert.AreEqual to compare your testVariable(s) with what is in {ClassName}.{Attribute} and/or the result variable you set when calling the action
//2. Call {ClassName}.{Action}({paremeter variables})
Valid Method Alternate Course Tests. What happens when it doesn’t have the data it needs?
Unit test Class {ClassName}{Action}When{Decision}Test
Unit test Method {ClassName}When{Decision}
//1. A variable defined of type {ClassName} and now with the code to construct it as well and the code to construct or fill every attribute. Test variable(s) containing the expected result state values of the object. If the action should return a value itself (it’s not setting attributes) then you also need a test variable to store the result of the action. If the action is dependent on data that IS NOT an attribute you would set that up here as well to pass as a parameter. Set the value that will cause the alternate path.
//3. Assert.IsNotNull() on the variable, can keep this here to make sure your setup is correct. Use Assert.AreEqual to compare your testVariable(s) with what is in {ClassName}.{Attribute} and/or the result variable you set when calling the action
//2. Call {ClassName}.{Action}({paremeter variables})
InValid Method Tests. What happens when it doesn’t have the data it needs?
Unit test Class {ClassName}{Action}Invalid{Attribute}Test
Unit test Method {ClassName}{Action}Invalid{Attribute}
//1. A variable defined of type {ClassName} and now with the code to construct it as well and the code to construct or fill every attribute. Test variable(s) containing the expected result state values of the object. If the action should return a value itself (it’s not setting attributes) then you also need a test variable to store the result of the action. If the action is dependent on data that IS NOT an attribute you would set that up here as well to pass as a parameter. Set the value for {Attribute} to be invalid.
//3. Assert.IsNotNull() on the variable, can keep this here to make sure your setup is correct. Use Assert.AreEqual to compare your testVariable(s) with what is in {ClassName}.{Attribute} and/or the result variable you set when calling the action
//2. Call {ClassName}.{Action}({paremeter variables})
Once you have functional tests around your classes you can add inheritance. The first step is almost like a construction test:
Unit test Class {ConstructedClassName}IsA{InheritedClassName}Test
Unit test Method {ConstructedClassName}IsA{InheritedClassName}
//1. A variable defined of type {InheritedClassName} You will need to create the class file now to remove the syntax error.
//3. Assert.IsNotNull() on the variable
//2. Construct the {ConstructedClassName} and put it in the variable. You will need to add Inheritance to pass the test.
Once you your inheritance tested
Go back to the tests testing the attributes that should be in the generalized class and change the type of the variable. Then you can safely move the attribute from the specialized class to the generalized class.
Go back to the tests testing the methods that should be in the generalized class and change the type of the variable. Then you can safely move the method from the specialized class to the generalized class.