2009-05-28 2 views
2

Я начинаю использовать Moq, и я не могу понять, как проверить метод Execute в коде ниже:Стыковка соединения с источником данных внутри функции с помощью Moq?

У меня есть следующий класс:

public class MyObject { 
    private IDataReaderPlugin m_source; 
    private IDataWriterPlugin m_dest; 
    private string[] m_dummyTags = new string[] { "tag1", "tag2", "tag3"}; 

    public void Execute(DateTime time) 
    { 
     DataCollection tags = m_source.SnapshotUtc(m_dummyTags, time); 

     //Doing some treatment on the values in tags  

     m_dest.Write(tags); 
    } 

}

другой метод отвечает за создание и инициализацию IDataReaderPlugin и IDataWriterPlugin из информации в файле конфигурации.

Я хочу протестировать метод Execute. Итак, мне нужно высмеять m_source и m_dest и после того, как я хочу протестировать результат, отправленный на m_dest.

Как я могу достичь этого с помощью Moq?

Спасибо.

ответ

2

Это поможет вам начать:

DateTime myDate = DateTime.Now; 

DataCollection tags = new DataCollection(); 

Mock<IDataReaderPlugin> dataReaderPlugin = new Mock<IDataWriterPlugin>(); 
dataReaderPlugin.Setup(drp => drp.SnapshotUtc(It.IsAny<string[]>(), myDate)).Returns(tags); 

Mock<IDataWriterPlugin> dataWriterPlugin = new Mock<IDataWriterPlugin>(); 
dataWriterPlugin.Setup(dwp => dwp.Write(tags);  

MyObject mo = new MyObject(); 
mo.Execute(); 

mock.Verify(foo => foo.Write(tags)); 
+0

Насколько я знаю, вы не можете на самом деле сделать It.IsAny () ... Я никогда не находил отличный способ обойти это:/ – womp

+0

Да, ответ был из моей памяти. Вы должны иметь возможность создать фиктивную строку [], а затем передать это. – rball

2

«Другой метод отвечает» - это ключевой бит информации. Если вы используете инфраструктуру IoC или DI, вам необходимо вставить некоторые Moq-макеты интерфейсов IDataReaderPlugin и IDataWriterPlugin. Тогда метод Execute будет использовать эти макеты, поставляемые каркасом IoC/DI.

Если они просто устанавливаются установщиком или имущества, то это так же просто, как:

// Arrange 
var mo = new MyObject(); 
var srcMock = new Mock<IDataReaderPlugin>(); 
src.Setup(src => src.SnapshotUtc(It.IsAny<string[]>(), It.IsAny<DateTime>())) 
    .Returns(new DataCollection() /* or whatever */); 
mo.SetSource(srcMock.Object); 
// ... same for m_dest 
// Act 
mo.Execute(DateTime.Now); 
// Assert 
// assert something... srcMock.Verify() or whatever 
+0

К сожалению, как класс предназначен, внутри класса создаются 2 интерфейса, поэтому я не могу вводить насмешливые интерфейсы. –

4
[Test] 
public void ShouldWriteToMDest() 
{ 
    // Arrange 
    var mockDest = new Mock<IDataWriterPlugin>(); 
    var mockSource = new Mock<IDataReaderPlugin>(); 
    string[] m_dummyTags = new string[] { "tag1", "tag2", "tag3"}; 

    mockSource.Setup(source => source.SnapshotUtc(m_dummyTags, It.IsAny<DateTime>()).Returns(/*whatever you need*/); 

    var myObj = new MyObject(mockSource.Object, mockDest.Object); 

    // Act 
    myObj.Execute(DateTime.Now); 


    // Assert 
    Assert.That(mockSource.Object.WhateverPropertyContainsOutput == /*Whatever you need */); 

} 
+0

Как бы то ни было, если вы не можете вставлять классы интерфейса в свой MyClass, это все равно нецелесообразно, так как ваш класс будет их создавать. Вы должны использовать конструктор, как то, что я показал в своем примере кода, для ввода зависимостей. – womp

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