2013-12-02 4 views
1

Похоже, что издевавшиеся сервисы совместно используются потребителями, как если бы издевавшиеся интерфейсы были одноточечными. Я использую комбинацию AutoMoq/Moq, если это актуально.Предотвращение создания Moq от создания одноточечных Mocks

class TestableClass 
{ 
    public IService service; 
    public TestableClass(IService s) { this.service = s } 
} 

Mocker.GetMock<IService>.Setup(s => s.Do()).Returns(1); 
var c1 = Mocker.Resolve<TestableClass>(); 
var c2 = Mocker.Resolve<TestableClass>(); 
Assert.That(c1, Is.Not.SameAs(c2)); // true 
Assert.That(c1.service, Is.NotSameAs(c2.service)) // false/fail 

Есть ли способ гарантировать, что IService является другим экземпляром каждый раз, когда создается экземпляр потребления? Причина в том:

Mocker.GetMock<IPauseTimer>() 
    .Setup(t => t.Begin(20)) 
    .Raises(t => t.Tick += null, new PauseTimerEventArgs(1)) 
    .Verifiable(); 

Когда я создаю мои два экземпляра тестов, они разделяют этот сингл PauseTimer, и когда c1 запускает функцию Begin, как c1 и c2 реагируют на события, когда только c1 должен.

+0

Я понимаю проблему (и ваше решение для работы). Но трудно понять, что вы на самом деле проверяете. Как 'PauseTimer' вписывается в TestableClass выше? Вы уверены, что пишете свой тест наилучшим образом? Эта проблема дает мне ощущение, что здесь немного странно. – MEMark

+1

@MEMark Первоначальная цель теста состояла в проверке синхронизации. Таймер не должен быть общим, но «TestableClass» должен отправить сообщение другому «TestableClass», чтобы синхронизировать состояние таймера. В принципе, в каждом классе есть секундомер, но запускается только один секундомер, который должен обновлять интерфейс обоих. Стоп-часы не могут быть одноточечными, так как во всей программе может быть несколько пар. –

ответ

1

Я работал вокруг этого, создавая еще один из насмешливый контейнер, который гарантирует, что экземпляры не являются одинаковыми.

var otherMocker = new AutoMoqer(); 
Mocker.GetMock<IService>.Setup(s => s.Do()).Returns(1); 
otherMocker.GetMock<IService>.Setup(s => s.Do()).Returns(1); 
var c1 = Mocker.Resolve<TestableClass>(); 
var c2 = otherMocker.Resolve<TestableClass>(); 
Assert.That(c1, Is.Not.SameAs(c2)); // true 
Assert.That(c1.service, Is.NotSameAs(c2.service)) // true 

Это не очень желательно, так как все работы по настройке необходимо было воспроизвести на этом другом контейнере. Вспомогательный метод помогает:

[SetUp] 
public void Setup() 
{ 
    Mocker = GetMoqer(); 
} 

AutoMoqer GetMoqer() 
{ 
    // configure base Mocker 
    return new AutoMoqer(); 
} 

[Test] 
public void TestWithDifferentInstances() 
{ 
    var s1 = Mocker.ResolveMock<IService>(); 
    var otherMocker = GetMoqer(); 
    var s2 = otherMocker.ResolveMock<IService>(); 
    Assert.That(s1, Is.Not.SameAs(s2)); 
} 
+0

Очень рад принять ответ, отличный от этого, если есть более простой метод. –