开发者

Why does the following test fail using Mbunit and Rhino mocks?

I am playing around with MbUnit and Rhino Mocks and made a simple test. It may be poorly designed code, but I am more focused on just seeing if I can get the test to pass. Basically, When the engine light of a car is on, the car should an oil change. Here is code:

public interface ICar
{
  开发者_StackOverflow  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
    }
 }


In this method:

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

    return false;
} 

you are calling GetOilChange(); on the object you are testing, and not on the mock you passed as a paramter. Hence this method indeed wasn't called on the mock. I guess you want to have this:

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


First off, this code has a bug. Add in the {} around the IF:

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

        return false;
    } 

The reason it fails is because you are calling new Car().CheckEngineLight ... and the new Car() is calling GetOilChange ... the carMock is not calling GetOilChange. Change the code to car.GetOilChange() (see it in the code above).

The fact that you are passing a Car object into a method on the Car Object is very confusing. Why not change the code to this:

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

    public void GetOilChange()
    {
    }

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

        return false;
    } 
}

Change your test to:

[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()); 
    }
 }


Your test is buggy, that's all. Change

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

to

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

Incidentally, this is probably more idiomatic for 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);
        }
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜