1
我有一些問題試圖使用RhinoMocks來弄清楚,如果在被測試的類中調用方法,也會調用其他一些方法。被測試 我的類:Rhinomocks:我不能正確使用AssertWasCalled
public class OrderMessageHandler : IHandleMessages<UpdateOrder>
{
public virtual IRepository Repository { get; set; }
public void Handle(UpdateOrder message)
{
if (!message.Order.Confirmed) return;
using (var om = new OperationManager())
{
try
{
om.BeginOperation();
LVR.Order.Model.OrderHeader order = ConvertToLocalOrderHeader(message.Order);
Repository.SaveUpdate(order);
om.CommitOperation();
}
catch (Exception ex)
{
om.RollbackOperation();
// other stuff here
}
}
}
internal virtual LVR.Order.Model.OrderHeader ConvertToLocalOrderHeader(Protocol.DTO.OrderHeader order)
{
// do stuff here, and call Repository.GetAll<Country>()
}
}
這裏是我的測試方法
[Fact]
public void ConvertToLocalOrderHeader_GivenConfirmedOrderMessage_CallTheConversionMethods()
{
// create a partial mock 'cause I want some of the implementation to be the true sut class
var sut = MockRepository.GeneratePartialMock<OrderMessageHandler>();
// create a stub for the repository, in order to avoid hitting the db
sut.Repository = MockRepository.GenerateStub<IRepository>();
sut.Repository.Stub(r => r.GetAll<Country>())
.Return(
new List<Country>
{
new Country {CountryID = "IT", Description = "Italy"},
new Country {CountryID = "US", Description = "United States"}
}.AsQueryable()
);
sut.Repository.Stub(r => r.SaveUpdate<OrderHeader>(Arg<OrderHeader>.Is.Anything));
// call the method I want to test
sut.Handle(new UpdateOrder
{
Order = order,
EventId = new Guid(),
EventTime = DateTime.Now
});
// verify that the method has been called (this is useless in my real test, I put it here just to understand why it doesn't work)
sut.AssertWasCalled(s => s.Handle(Arg<UpdateOrder>.Is.Anything));
// verify that an inner method (virtual) has been called during the execution of sut.handle()
sut.AssertWasCalled(s => s.ConvertToLocalOrderHeader(order));
}
在2個sut.AssertWasCalled
電話,我收到一個錯誤對象引用不設置到對象的實例。 。其原因是,sut.AssertWasCalled
作出的方法我正在驗證一個電話......這樣
sut.AssertWasCalled(s => s.Handle(Arg<UpdateOrder>.Is.Anything));
電話
sut.Handle(null)
而且是空的方法拋出一個異常的參數。 問題太糟糕了,它不應該重新調用這個方法,而只是告訴我它在測試方法之前是否從未被調用過。 這裏有什麼問題?
編輯:
按在收到的意見建議,我嘗試了不同的方法(因爲我不喜歡的期望/驗證味)。這裏的測試方法:
[Fact]
public void ConvertToLocalOrderHeader_GivenConfirmedOrderMessage_CallTheConversionMethods2()
{
var mocks = new MockRepository();
var sut = mocks.PartialMock<OrderMessageHandler>();
sut.Repository = mocks.Stub<IRepository>();
sut.Repository.Stub(r => r.GetAll<Country>())
.Return(
new List<Country>
{
new Country {CountryID = "IT", Description = "Italy"},
new Country {CountryID = "US", Description = "United States"}
}.AsQueryable()
);
sut.Repository.Stub(r => r.SaveUpdate<OrderHeader>(Arg<OrderHeader>.Is.Anything));
Expect.Call(() => sut.Handle(Arg<UpdateOrder>.Is.Anything));
sut.Replay();
sut.Handle(new UpdateOrder
{
Order = order,
EventId = new Guid(),
EventTime = DateTime.Now
});
mocks.VerifyAll();
}
ADN這裏是我的錯誤:
System.InvalidOperationException
Previous method 'OrderMessageHandler.get_Repository();' requires a return value or an exception to throw.
錯誤是由代碼行,即使這種方法拋出
Expect.Call(() => sut.Handle(Arg<UpdateOrder>.Is.Anything));
所以,沒有運氣...
還有其他想法嗎?
您可以嘗試使Handle方法爲虛擬嗎?除非你這樣做,否則我認爲犀牛不能在這種情況下重寫該方法。 – 2014-08-27 14:53:26
mh,你是對的......太糟糕了總體行爲沒有任何變化:我仍然有同樣的問題 – themarcuz 2014-08-27 15:08:00
我想在你的情況下使用Excpect,就像這個例子http://ayende.com/wiki/Rhino+Mocks + Partial + Mocks.ashx?AspxAutoDetectCookieSupport = 1 – 2014-08-27 15:27:41