Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are the unit test classes in ASP.NET MVC web project a good example?

I'm learning TDD. I know about dependency injection whereby you place the class's dependencies in the constructor's parameters and have them passed in, passing in default implementations from the default constructor eg;

public AccountController() : this( RepositoryFactory.Users())
{
}

public AccountController( IUserRepository oUserRepository)
{
 m_oUserRepository = oUserRepository;
}

RepositoryFactory is a simple static class that returns the chosen implementations for the current build

But the default ASP.NET MVC web app project doesn't do this, instead the DI takes the form of public properties that are assigned in the object initializer in the test class eg; from AccountController.cs :

protected override void Initialize(RequestContext requestContext)
{
 if (FormsService == null)
  { FormsService = new FormsAuthenticationService(); }
 if (MembershipService == null)
  { MembershipService = new AccountMembershipService(); }

 base.Initialize(requestContext);
}

And in the test class AccountControllerTest.cs :

private static AccountController GetAccountController()
{
 AccountController controller = new AccountController()
 {
  FormsService = new MockFormsAuthenticationService(),
  MembershipService = new MockMembershipService(),
  Url = new UrlHelper(requestContext),
 };
 //snip
}

So now my AccountController class has two approaches to dependency injection. Which one should I use? Constructor injection or public properties?

Am thinking constructor injection...

Is the ASP.NET MVC use of public properties like that because you need to provide a specific way of injecting into the constructor, and the basic "create new" web app needs to be generic as a starting point?

like image 479
Typo Johnson Avatar asked Jan 23 '11 00:01

Typo Johnson


People also ask

Are frontend unit tests useful?

Unit testing It analyzes individual components and functions to ensure they're working as expected. This is crucial for any frontend application, testing your components and features against how you expect them to behave in production, leading to a stable codebase and a reliable app for your customers.

Is unit test used in game development?

Programming is programming. Unit tests are useful for any kind of application because they help you detect and correct errors (and often more importantly, regressions inadvertently introduced as you refactor code) immediately and efficiently.


2 Answers

The examples in the ASP.NET MVC are excellent demonstrations of how not to use DI.

First of all, using a default constructor as well as an overloaded constructor introduces ambiguity: does the class control its own dependencies, or does it get them from the outside? Apparently, it can't really decide.

Secondly, having a default implementation introduces tight coupling because you can't create a new instance of the default implementation without having a reference to it. However, the whole point of DI is to enable loose coupling.

Unfortunately we see this idiom a lot. In my book I call it the Bastard Injection anti-pattern; I lifted the name from one of Oren Eini/Ayende Rahien's many opinionated blog posts where he walks through a very similar example.

As a general advice I recommend using Constructor Injection in the vast majority of cases. It's easy to implement and has very strong semantics: it forces the consumer to supply an instance of the dependency, effectively stating that the dependency is mandatory.

Property Injection, on the other hand, implies that the dependency is optional, because the compiler doesn't force you to assign a value. In most cases, dependencies are not really optional, so use of this pattern should be rare.

like image 195
Mark Seemann Avatar answered Nov 14 '22 22:11

Mark Seemann


Take a look at structuremap. You are correct...constructor injection is the preferred method of DI/IoC. Check out this article by Martin Fowler. Hope this helps you.

like image 33
jsteve81 Avatar answered Nov 14 '22 22:11

jsteve81