patterncsharpMinor
Unit Testing an AppInfo class
Viewed 0 times
appinfoclasstestingunit
Problem
I have never written a unit test and I am really new to C#. I am attempting to test a method, am I testing for the right things here?
The Method
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using Orlean.Properties;
namespace Orlean.Helpers
{
public enum SemverFormat
{
Full,
Version,
Major,
Minor,
Patch,
Micro,
Pre,
Meta
}
public class AppInfo
{
// Grab the SemVer from assembly
// You may pass any value 0-6 for id
// SemverFormat.Full or nothing will return the entire SemVer string (X.Y.Z-pre+meta)
// SemverFormat.Version will return the SemVer Major.Minor.Patch/Micro (X.Y.Z)
// SemverFormat.Major will return the SemVer Major (X)
// SemverFormat.Minor will return the SemVer Minor (Y)
// SemverFormat.Patch or SemverFormat.Micro will return the SemVer Patch/Micro (Z)
// SemverFormat.Pre will return the SemVer Pre data
// SemverFormat.Meta will return the SemVer Meta data
public static string SemverPart(SemverFormat? Option = SemverFormat.Full)
{
var attribute = Assembly.GetExecutingAssembly().GetCustomAttributes(false).OfType().FirstOrDefault();
string semver = (attribute == null) ? string.Empty : attribute.GetVersion;
string[] delimiter = { "-", "+" };
var semverArray = semver.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
var versionArray = semverArray[0].Split('.');
switch (Option)
{
case SemverFormat.Version:
return semverArray[0] ?? string.Empty;
case SemverFormat.Major:
return versionArray[0] ?? string.Empty;
case SemverFormat.Minor:
return versionArray[1] ?? string.Empty;
case SemverFormat.Patch:
The Method
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using Orlean.Properties;
namespace Orlean.Helpers
{
public enum SemverFormat
{
Full,
Version,
Major,
Minor,
Patch,
Micro,
Pre,
Meta
}
public class AppInfo
{
// Grab the SemVer from assembly
// You may pass any value 0-6 for id
// SemverFormat.Full or nothing will return the entire SemVer string (X.Y.Z-pre+meta)
// SemverFormat.Version will return the SemVer Major.Minor.Patch/Micro (X.Y.Z)
// SemverFormat.Major will return the SemVer Major (X)
// SemverFormat.Minor will return the SemVer Minor (Y)
// SemverFormat.Patch or SemverFormat.Micro will return the SemVer Patch/Micro (Z)
// SemverFormat.Pre will return the SemVer Pre data
// SemverFormat.Meta will return the SemVer Meta data
public static string SemverPart(SemverFormat? Option = SemverFormat.Full)
{
var attribute = Assembly.GetExecutingAssembly().GetCustomAttributes(false).OfType().FirstOrDefault();
string semver = (attribute == null) ? string.Empty : attribute.GetVersion;
string[] delimiter = { "-", "+" };
var semverArray = semver.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
var versionArray = semverArray[0].Split('.');
switch (Option)
{
case SemverFormat.Version:
return semverArray[0] ?? string.Empty;
case SemverFormat.Major:
return versionArray[0] ?? string.Empty;
case SemverFormat.Minor:
return versionArray[1] ?? string.Empty;
case SemverFormat.Patch:
Solution
I will give a general overview of things you should change but definitely take a look at some of my answers related to unit testing I will put at the bottom.
Naming
I very much advise to use a naming scheme like
In a different situation it could be
Small - Smaller - Smallest - A Good Unit test
Unit tests test one unit and they assert to one set of related post-conditions. They are also void of logic since all they should be able to do is perform an action and confirm the results.
You are testing
There are many benefits to splitting tests up in the smallest units possible but this should already be enough (this doesn't mean aggregated units aren't important; you should test all units: even those that are composed of other units).
Logic
No logic in your test! Instead use multiple tests to test the different scenarios. For reasons: see above.
Misc
I have no idea what
I would make
Reading
Naming
I very much advise to use a naming scheme like
[UnitOfWorkName]_[ScenarioUnderTest]_[ExpectedBehaviour]. I would give an example in your situation but I can't because your test is very unclear (red flag). In a different situation it could be
AddUser_WithoutFirstname_ThrowsArgumentException. When this test fails I know exactly what scenario doesn't work and I don't have to look at the actual code to figure out what it does; consider it a summary.Small - Smaller - Smallest - A Good Unit test
Unit tests test one unit and they assert to one set of related post-conditions. They are also void of logic since all they should be able to do is perform an action and confirm the results.
You are testing
AppInfo.SemverPart() with the different options. An sich this is fine, but they are multiple different actions so every single one of them should be separated into its own unit test. Yes, you will now have 10 very small unit tests; your manager will be impressed. You will also have a very clear overview in your test results window about what inputs worked and what ones didn't.There are many benefits to splitting tests up in the smallest units possible but this should already be enough (this doesn't mean aggregated units aren't important; you should test all units: even those that are composed of other units).
Logic
No logic in your test! Instead use multiple tests to test the different scenarios. For reasons: see above.
Misc
I have no idea what
SemverPart does or means; refactor this into a name in the form of [action][context] (for example: GetVersion()).I would make
stripCharacters private since the outside world doesn't need it (even if nobody calls it, it's good practice).Reading
- Naming unit tests
- Naming unit tests (2)
- What is a bad unit test?
- What should I test?
- What should I test? (2)
- How complex should unit tests be?
- Should I test private methods?
- Will unit tests help me document code?
Context
StackExchange Code Review Q#52670, answer score: 5
Revisions (0)
No revisions yet.