фиктивный объект, который реализует получает и устанавливает не определенные в интерфейсе - PullRequest
3 голосов
/ 06 июня 2011

Используя Moq, RhinoMocks или аналогичную инфраструктуру, есть ли способ настроить макет для реализации как получения, так и установки всех свойств объекта, даже если интерфейс этого не делает?

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

Вот пример кода:

//interface to be mocked
public interface IMyObject
{
    string Property1 { set; }
}

//test method code
var mock = Moq.Mock<IMyObject>();

//...some code here to configure all properties on mock to have a get and set...

var mockObject = mock.Object;

ClassUnderTest obj = new ClassUnderTest(mockObject);
obj.MethodUnderTest();

Assert.IsTrue(!String.IsNullOrEmpty(mockObject.Property1));    

Запуск кода «как есть» вызовет исключение для mockObject.Property1, поскольку в свойстве IMyObject.Property1 отсутствует метод доступа get.

Спасибо, Дано

Ответы [ 4 ]

4 голосов
/ 07 июня 2011
public class Test
{
    public void AssertOneElement()
    {
        var mock = new Mock<IMyObject>();
        var list = default(IList<int>);

        mock.SetupSet(x => x.Property1 = It.IsAny<IList<int>>())
            .Callback<IList<int>>(value => list = value);

        // Fails
        mock.Object.Property1 = new List<int>();

        // Succeeds
        // mock.Object.Property1 = new List<int>(new[] { 1 });

        Debug.Assert(list != null);
        Debug.Assert(list.Count == 1, "Called with a list that did not contain a single element!");
    }
}

public interface IMyObject
{
    IList<int> Property1 { set; }
}
1 голос
/ 07 июня 2011

Для списка:

var mock = new Mock<IMyObject>();

// your test code

mock.VerifySet(x => x.Property1 = It.Is<IList<int>>(l => l != null && l.Count > 0));
1 голос
/ 06 июня 2011

Используя Moq, это работает:

var mock = new Mock<IMyObject>();

// test code goes here

// Note single equals sign, not double equals
mock.VerifySet(x => x.Property1 = "expected");

SetupAllProperties НЕ работает.

1 голос
/ 06 июня 2011

Используя Rhino Mocks, вы можете установить ожидание для свойства.В основном это означает, что вы ожидаете, что для свойства будет установлено определенное значение.Используя ваш пример, пример тела метода теста будет таким:

var mock = MockRepository.GenerateMock ();mock.Expect (x => x.Property1 = "Test");

var classUnderTest = new ClassUnderTest(mock);
classUnderTest.MethodUnderTest();

mock.VerifyAllExpectations();

Это позволит проверить, было ли для Property1 установлено значение "Test" в какой-то момент между вызовом mock.Expect и вызов mock.MethodUnderTest (технически, Property1 может быть установлен в конструкторе ClassUnderTest).

Чтобы проверить, что свойство было установлено, и игнорировать то, что оно было фактически установлено,просто соедините IgnoreArguments с возвращением вызова Expect, например:

mock.Expect (x => x.Property1 = "Test1"). IgnoreArguments ();

Один из способов проверить более сложные свойства только для записи - использовать метод GetArgumentsForCallsMadeOn.Это позволяет вам получить список аргументов, передаваемых каждому «вызову» свойства.Код для этого будет выглядеть следующим образом:

var mock = MockRepository.GenerateMock ();

var classUnderTest = new ClassUnderTest(mock);
classUnderTest.MethodUnderTest();

//the argument in the Action is ignored, so just use null
//Property1 is of type List<string>
var arguments = mock.GetArgumentsForCallsMadeOn(x => x.Property1 = null);

//arguments[0] contains the list of arguments for the first "call" of the
//property the first index (0) of that would contain the first argument
var firstCallArguments = arguments[0];
var firstArgument = (List<string>)firstCallArguments[0];
Assert.AreEqual(3, firstArgument.Count);

Я уверен, что Moq имеет аналогичную функциональность, если вы хотите использоватьэто вместо этого.

...