Почему следующий тест не выполняется с использованием насмешек Mbunit и Rhino? - PullRequest
1 голос
/ 09 сентября 2010

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

public interface ICar
{
    bool EngineLight { get; set; }
    void GetOilChange();
    bool CheckEngineLight(ICar car);
}

public class Car : ICar
{
    public bool EngineLight { get; set; }

    public void GetOilChange()
    {
    }

    public bool CheckEngineLight(ICar car)
    {
        if (car.EngineLight)
            GetOilChange();
            return true;

        return false;
    } 
}

[TestFixture]
public class CarTests
{
[Test]
    public void WhenEngineLightIsOnGetOilChange()
    {
        var carMock = MockRepository.GenerateMock<ICar>();
        carMock.Stub(x => x.EngineLight).Return(true);

        Assert.AreEqual(true, new Car().CheckEngineLight(carMock)); //This passes

        carMock.AssertWasCalled(x => x.GetOilChange()); //This fails
    }
 }

Ответы [ 3 ]

4 голосов
/ 09 сентября 2010

В этом методе:

public bool CheckEngineLight(ICar car)
{
    if (car.EngineLight)
        GetOilChange();
        return true;

    return false;
} 

вы вызываете GetOilChange (); на объекте, который вы тестируете, а не на макете, который вы передали как параметр Следовательно, этот метод действительно не был вызван на макет. Я думаю, вы хотите иметь это:

public bool CheckEngineLight(ICar car)
{
    if (car.EngineLight)
    {
        car.GetOilChange();
        return true;
    }
    return false;
} 
3 голосов
/ 09 сентября 2010

Во-первых, в этом коде есть ошибка. Добавьте в {} вокруг IF:

public bool CheckEngineLight(ICar car)
    {
        if (car.EngineLight)
        {
            car.GetOilChange();
            return true;
        }

        return false;
    } 

Причиной сбоя является то, что вы вызываете новый Car (). CheckEngineLight ... и новый Car () вызывает GetOilChange ... carMock не вызывает GetOilChange. Измените код на car.GetOilChange() (см. Код выше).

Тот факт, что вы передаете объект Car в метод объекта Car, очень запутан. Почему бы не изменить код на это:

public class Car : ICar
{
    public bool EngineLight { get; set; }

    public void GetOilChange()
    {
    }

    public bool CheckEngineLight()
    {
        if (EngineLight)
        {
            GetOilChange();
            return true;
        }

        return false;
    } 
}

Измените свой тест на:

[Test]
    public void WhenEngineLightIsOnGetOilChange()
    {
        var carMock = MockRepository.GenerateMock<ICar>();
        carMock.Stub(x => x.EngineLight).Return(true);

        Assert.AreEqual(true, carMock.CheckEngineLight()); 

        carMock.AssertWasCalled(x => x.GetOilChange()); 
    }
 }
2 голосов
/ 09 сентября 2010

Ваш тест глючит, вот и все.Измените

GetOilChange(); // calls the car instance, not the mock, your
                // AssertMethodCalled will never be true

на

car.GetOilChange(); // calls the mock you passed in

Кстати, это, вероятно, более идиоматично для Rhino:

public interface ICar
{
    bool EngineLight { get; set; }
    void GetOilChange();
    bool CheckEngineLight();
}

public class Car : ICar
{
    public bool EngineLight { get; set; }

    public virtual void GetOilChange()
    {
    }

    public virtual bool CheckEngineLight()
    {
        if (EngineLight)
        {
            GetOilChange();
            return true;
        }

        return false;
    }
}

[TestFixture]
public class CarTests
{
    [Test]
    public void WhenEngineLightIsOnGetOilChange()
    {
        MockRepository mocks = new MockRepository();

        Car car;
        using (mocks.Record())
        {
            car = mocks.PartialMock<Car>();
            car.EngineLight = true;

            car.Expect(x => x.GetOilChange())
                .Repeat.Once()
                .Message("Should have called GetOilChange");

        }

        using (mocks.Playback())
        {
            var res = car.CheckEngineLight();
            Assert.IsTrue(res);
        }
    }
}
...