Moq multi интерфейсы - PullRequest
       14

Moq multi интерфейсы

0 голосов
/ 02 апреля 2012

Справочная информация:

Я развернул простую функцию прокси для моего клиента Wcf, основываясь частично на примерах, найденных в Интернете, и частично на моих потребностях.

Использование для создания клиентского прокси как его известно:

WcfClientProxy<IServicecontract> clientProxy = 
                                 new WcfClientProxy<IServiceContract>();

WcfClientProxy имеет метод Execute, который принимает: Expression<Func<TChannel, TResult>> или Expression<Action<TChannel>>.

Чего я пытаюсь достичь:

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

Так что издевайтесь над этим звонком ..

clientProxy.Execute(m=>m.DoSomeAction(5));

Проблема:

Проблема в том, что макет не работает. Я получаю эту ошибку:

"бросил исключение: System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта. "

Мой контракт на тестовое обслуживание:

public interface ITestingServiceInterface : System.ServiceModel.IClientChannel
{
    string Version();
    VersionDetail VersionDetail();
    IList<VersionDetail> VersionDetails();
    void DoSomeDelete(int itemId);
}

Интерфейс прокси клиента wcf:

public interface IWcfClientProxy<TChannel> where TChannel : ICommunicationObject
{
    bool ThrowOnException { get; set; }
    TResult Execute<TResult>(Expression<Func<TChannel, TResult>> operation);
    void Execute(Expression<Action<TChannel>> expression);
}

Мой тест и макет с настройкой ..

private List<ProdItem> items;
private Mock<IWcfClientProxy<ITestingServiceInterface>> mockClientProxy;

[TestInitialize]
public void SettingUp()
{
    mockClientProxy = new Mock<IWcfClientProxy<ITestingServiceInterface>>();

    items = new List<ProdItem>();
    for( int i =0; i<10; i++){
        items.Add(new ProdItem { ProdItemId = i, LocalStock = i });
    }
}

[TestMethod]
public void SimpleTest()
{
    mockClientProxy.Setup(m => m.Execute(x => x.DoSomeDelete(It.IsAny<int>()))).Callback(RemoveItem);

    var client = mockClientProxy.Object;

    client.Execute(x => x.DoSomeDelete(4));

    Assert.AreEqual(9, items.Count);
}

public void RemoveItem()
{
    items.RemoveAt(items.Count - 1);
}

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

Я уверен, что только что сделал глупость.

Обновление: Показаны примеры того, что я хотел бы проверить, сработало ли вышеизложенное ..

[TestMethod]
public void SimpleTest()
{
    mockClientProxy.Setup(m => m.Execute(x => x.DoSomeDelete(It.IsAny<int>()))).Callback(RemoveItem);

    var client = mockClientProxy.Object;

    var stockHelper = new StockHelper(client);

    stockHelper.DeleteItem(5);

    Assert.AreEqual(9, items.Count);
}

Выше я тестирую класс StockHelper, который принимает прокси клиента в своем конструкторе, через который он обращается к WCF.

Чтобы протестировать StockHelper (или что-то еще), мне нужно иметь возможность высмеивать клиента и его сервисные вызовы. Приведенный выше (1-й) пример показывает, что у меня возникла проблема при попытке сделать это.

Надеюсь, это имеет смысл, пожалуйста, обратите внимание, что моей конечной целью является не тестирование макета ... это как раз то, где я пытался отладить мою проблему.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2012

Как я вижу из вашего кода, вы тестируете макет. Я не вижу ни одного реального объекта, который вы тестируете. Насмешки используются для заглушения зависимостей тестируемых объектов Итак, если какой-то класс Foo использует IWcfClientProxy, вы предоставляете макет этого прокси для класса Foo. И убедитесь, что во время Foo.Bar() был вызван метод выполнения DoSomeDelete зависимости. Это цель издевательств.

[TestClass]
public class FooTests
{
   private Foo _foo;
   private Mock<IWcfClientProxy<ITestingServiceInterface>> _clientProxy;

   [TestInitialize]
   public void SettingUp()
   {
       _clientProxy = new Mock<IWcfClientProxy<ITestingServiceInterface>>();
       _foo = new Foo(_clientProxy.Object);
   }

   [TestMethod]
   public void SimpleTest()
   {
       // Act on object being tested
       _foo.Bar(5);

       // verify it executed correct method on dependency
       _clientProxy.Verify(cp => cp.Execute(x => x.DoSomeDelete(5)));
    }
}

Имейте в виду, что при тестировании Foo вас не должно волновать, как реализован _clientProxy.

0 голосов
/ 26 января 2015

Что-то странное происходит в вашей настройке.Я думаю, что параметры, которые вы устанавливаете, ограничены первым уровнем вызовов функций.Вам может потребоваться сделать что-то вроде:

mockClientProxy.Setup(m => m.Execute(It.IsAny<Expression<Action<TChannel>>>())).Callback(RemoveItem);

Moq работает путем реализации методов на интерфейсе своего аргумента, в данном случае это методы интерфейса IWcfClientProxy<ITestingServiceInterface>.Поэтому, когда вы настраиваете вызов метода для Execute, вам нужно настроить соответствующие параметры для аргументов для Execute.Что вы сделали в своем коде, так это установили соответствие для этой конкретной функции-делегата, которая на самом деле никогда ничего не будет совпадать, потому что вы не сохраните ее и не вызовете Execute с ней позже.

...