Próbując przylegają do D w SOLID
Dependency zasadzie inwersji gdzie jeden powinien „zależeć abstrakcje. Nie zależą od konkrecji
dla projektu. W tym przypadku Asp.Net-MVC5, chciałem, aby upewnić się, że wszystkie kontrolery (MVC i WebAPI2) podążały za tym wzorcem, w którym nie były zależne od konkrecji.
Pierwotny pomysł pochodzi z artykułu, który przeczytałem, gdzie utworzono test jednostkowy, aby zeskanować wszystkie kontrolery, aby upewnić się, że zostały zdefiniowane wyraźne uprawnienia. Zastosowałem podobne myślenie, sprawdzając, czy wszystkie kontrolery mają konstruktory zależne od abstrakcji.
[TestClass]
public class ControllerDependencyTests : ControllerUnitTests {
[TestMethod]
public void All_Controllers_Should_Depend_Upon_Abstractions() {
var controllers = UnitTestHelper.GetAssemblySources() //note this is custom code to get the assemblies to reflect.
.SelectMany(assembly => assembly.GetTypes())
.Where(t => typeof(IController).IsAssignableFrom(t) || typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(t));
var constructors = controllers
.SelectMany(type => type.GetConstructors())
.Where(constructor => {
var parameters = constructor.GetParameters();
var result = constructor.IsPublic
&& parameters.Length > 0
&& parameters.Any(arg => arg.ParameterType.IsClass && !arg.ParameterType.IsAbstract);
return result;
});
// produce a test failure error mssage if any controllers are uncovered
if (constructors.Any()) {
var errorStrings = constructors
.Select(c => {
var parameters = string.Join(", ", c.GetParameters().Select(p => string.Format("{0} {1}", p.ParameterType.Name, p.Name)));
var ctor = string.Format("{0}({1})", c.DeclaringType.Name, parameters);
return ctor;
}).Distinct();
Assert.Fail(String.Format("\nType depends on concretion instead of its abstraction.\n{0} Found :\n{1}",
errorStrings.Count(),
String.Join(Environment.NewLine, errorStrings)));
}
}
}
Tak biorąc pod uwagę następujący przykład. (Zauważ, że ten przystosowany do MVC)
public class MovementController : Controller {
public MovementController(MotorController motorController) {
//...
}
}
public interface IMotorController {
//...
}
public class MotorController : IMotorController {
//...
}
test jednostka nie powiedzie się z ...
Result Message: Assert.Fail failed.
Type depends on concretion instead of its abstraction.
1 Found :
MovementController(MotorController motorController)
ten pracował dla mnie, bo miałem wspólny typ szukać z IController
i ApiController
.
Jest miejsce na ulepszenie w teście, ale powinno być dobrym punktem wyjścia dla ciebie.
Zobaczmy, rozumiem: Chcesz test jednostkowy, aby sprawdzić, czy kontrolery mają tylko interfejsy jako argumenty konstruktora? jaki to jest projekt? MVC, winform, wpf ...? – Nkosi