sfeldman.NET

.NET, code, personal thoughts

Factory per DTO

Today one of our team members brought up a valid question - how do I know that my SUT (system uder test) packages the primitive parameters (username and password) and sends into dependency object as a DTO. Maybe instead of packaging into DTO the primitive values it packages something else by accident. The proposed solution was a dedicated Factory per each DTO (contract and implementation). For testing purpose it was great, but from the design perspective this is an absolute no-no. Lets review what we have and what we want to have.

Have:

- A SUT that leverages a dependency to perform a task

- Communication to SUT is done with primitive types (2 strings in this case)

- Dependency requires primitives to be sent as a DTO

Want to have:

- Test on SUT that does interaction testing with dependency

- Verify that parameters provided to SUT are propagated into dependency and no surprises with that take place

How to achieve what we need? We have to ensure that whatever dependency was called with is matching what the SUT was invoked with. It doesn’t mean we have to have a factory. Here’s an example:

   1: using Library.Infrastructure;
   2: using Rhino.Mocks;
   3:  
   4: namespace Library
   5: {
   6:     [Concern(typeof(ServiceContract))]
   7:     public abstract class ServiceContract_Specs : ContextSpecification<IServiceContract>
   8:     {
   9:         protected IDomainService domainService;
  10:  
  11:         protected override IServiceContract create_system_under_test()
  12:         {
  13:             return new ServiceContract(domainService);
  14:         }
  15:  
  16:         protected override void establish_context()
  17:         {
  18:             system_under_test = create_system_under_test();
  19:         }
  20:     }
  21:  
  22:     public class When_service_is_asked_to_validate_a_user_with_provided_user_name_and_password : ServiceContract_Specs
  23:     {
  24:         private const string username = "username";
  25:         private const string password = "password";
  26:  
  27:         protected override void establish_context()
  28:         {
  29:             domainService = dependency<IDomainService>();
  30:             domainService.setup_result(x => x.ValidateUser(Arg<UserDto>.Is.NotNull)).Return(true);
  31:             base.establish_context();
  32:         }
  33:  
  34:         protected override void because()
  35:         {
  36:             system_under_test.Validate(username, password);
  37:         }
  38:  
  39:         [Observation]
  40:         public void Should_leverage_domain_service_to_validate_a_user()
  41:         {
  42:             domainService.was_told_to(x => x.ValidateUser(Arg<UserDto>.Matches(
  43:                 dto => userdto_details_match_username_and_password(dto))));
  44:         }
  45:  
  46:         private bool userdto_details_match_username_and_password(UserDto dto)
  47:         {
  48:             return dto.Username.Equals(username) && dto.Password.Equals(password);
  49:         }
  50:     }
  51: }

The underlined code is verifying what we “want to have” without having a factory in place. A simple predicate replaces requirement in Factory per DTO just for testing needs.

I am opened for discussions, but pretty sold on the fact that Factory per DTO is a waste of time.

Update: updated the establish_context to setup a proper result (domain service, ValidateUser behavior is returning a value).

Published Thursday, January 29, 2009 9:29 AM by Sean Feldman
Filed under: ,

Comments

# re: Factory per DTO@ Friday, January 30, 2009 5:18 AM

That's a class name and a half:

When_service_is_asked_to_validate_a_user_with_provided_user_name_and_password

# re: Factory per DTO@ Friday, January 30, 2009 8:14 AM

@coppermill,

that's what it takes to be descriptive. Is it a concern - don't think so.

# Bj??rn Rochel&#8217;s weblog &raquo; Verifying indirect outputs with Rhino.Mocks in xUnit.BDDExtensions@ Friday, January 30, 2009 4:51 PM

Pingback from  Bj??rn Rochel&#8217;s weblog &raquo; Verifying indirect outputs with Rhino.Mocks in xUnit.BDDExtensions