2013-11-15 8 views
3

У меня возникла странная проблема, связанная с AutoFixture и AutoMoqCustomization и как она связана с автоматизацией конкретных классов. Я подозреваю, что я не очень хорошо его использую, но хотел бы знать, в чем проблема. Прежде всего, это какой-то контекст. Скажем, у меня есть класс, который я хочу, чтобы тест:AutoFixture с инъекцией AutoMoq и бетонных объектов

public class IdentityApplicationService 
{ 
    public IdentityApplicationService(
     TenantProvisioningService tenantProvisioningService) 
    { 
     // guard clause etc. 
     _tenantProvisioningService = tenantProvisioningService; 
    } 
} 

и его класс зависимостей TenantProvisioningService (зависимости TenantProvisioningService не имеют отношения здесь, потому что они будут автоматически издевались, и я не забочусь о том, в моем тесте):

public class TenantProvisioningService 
{ 
    readonly IRoleRepository _roleRepository; 
    readonly ITenantRepository _tenantRepository; 
    readonly IUserRepository _userRepository; 

    public TenantProvisioningService(
     ITenantRepository tenantRepository, 
     IUserRepository userRepository, 
     IRoleRepository roleRepository) 
    { 
     this._roleRepository = roleRepository; 
     this._tenantRepository = tenantRepository; 
     this._userRepository = userRepository; 
    } 
} 

и вот мой простой тест:

[Fact] 
public void ShouldReturnTenantWhenCallingProvisionTenant() 
{ 
    var fixture = new Fixture().Customize(new AutoMoqCustomization()); 
    var mockTenantProvisioningService = 
     fixture.Freeze<Mock<TenantProvisioningService>>(); 
    var sut = fixture.Create<IdentityApplicationService>(); 
    var command = new ProvisionTenantCommand(
     "bla", 
     "bla SaaS platform", 
     "superadmin", 
     "superadmin", 
     "[email protected]", 
     null, 
     null, 
     null, 
     null, 
     null, 
     null, 
     null); 
    var tenant = sut.ProvisionTenant(command); 

    // some asserts 
} 

Это не работает, потому что, когда я называю fixture.Create<IdentityApplicationService>() то в это constructo r конкретный TenantProvisioningService вводится вместо проксированного, который вы можете найти в mockTenantProvisioningService.Object.

Если я переписать тест, как это (обратите внимание на крепление INJECT линии) все работает, как ожидалось (мной по крайней мере :))

[Fact] 
public void ShouldReturnTenantWhenCallingProvisionTenant() 
{ 
    var fixture = new Fixture().Customize(new AutoMoqCustomization()); 
    var mockTenantProvisioningService = 
     fixture.Freeze<Mock<TenantProvisioningService>>(); 
    fixture.Inject(mockTenantProvisioningService.Object); 
    var sut = fixture.Create<IdentityApplicationService>(); 
    var command = new ProvisionTenantCommand(
     "bla", 
     "bla SaaS platform", 
     "superadmin", 
     "superadmin", 
     "[email protected]", 
     null, 
     null, 
     null, 
     null, 
     null, 
     null, 
     null); 
    var tenant = sut.ProvisionTenant(command); 

    // some asserts 
} 

Так что мой вопрос: Могу ли я делать это неправильно или так оно и должно быть? Если нет, объясните, почему AutoFixture ведет себя так.

+1

* AutoMoq * игнорирует конкретные классы, поэтому вы видите это поведение: http://blog.ploeh.dk/2010/08/25/ChangingthebehaviorofAutoFixtureauto-mockingwithMoq IOW, это ожидается. –

+0

Хотя я понимаю, что это ожидалось, не побеждает ли принцип наименьшего удивления? –

+1

Я не знаю - сюрприз зависит от того, что вы ожидаете ... В этом случае, я думаю, это также удивит вас, если * все * экземпляры внезапно оказались издевательствами над их типами ... На самом деле, я не уверенный, что я могу понять все последствия такого изменения в поведении ... который также был мотивирующим фактором при его проектировании, как сейчас. –

ответ

6

As Mark Seemann points out, это ожидаемое поведение.

Ниже приведен код из the original post обновлена ​​для работы с текущей версией AutoFixture:

Func<ISpecimenBuilder, bool> concreteFilter = 
    sb => !(sb is MethodInvoker); 

var relays = new FilteringRelays(concreteFilter); 

var fixture = new Fixture(relays).Customize(
    new AutoMoqCustomization(
     new MockRelay(
      new TrueRequestSpecification()))); 

FilteringRelays класса остается тем же самым.

 Смежные вопросы

  • Нет связанных вопросов^_^