我有以下代碼:如何使用Rhino.Mocks模擬某些代碼?
public interface IFlowFolderHandler
{
OperationResult Post(FlowFolder dto);
}
public class FlowFolderHandler : IFlowFolderHandler
{
private readonly IResponse m_response;
private readonly IEntityRepository m_entityRepository;
public FlowFolderHandler(IResponse response, IEntityRepository entityRepository)
{
m_response = response;
m_entityRepository = entityRepository;
}
public OperationResult Post(FlowFolder dto)
{
var ent = FlowFolderX.Cast(dto, true);
m_entityRepository.Update(ent);
var id = EntityIdComparer.IdToString(ent.Id);
m_response.Headers["X-Entity-Id"] = id;
return new OperationResult.Created
{
RedirectLocation = new Uri("FlowFolder/" + id, UriKind.Relative),
ResponseResource = ent.GetEntityRelation(),
};
}
}
我想單元測試FlowFolderHandler.Post
方法,使用IResponse
和IEntityRepository
嘲笑。我目前的實現是使用以下手冊嘲笑:
private class EntityRepositoryMock : IEntityRepository
{
private readonly Action<IEntityBase> m_update;
public EntityRepositoryMock(int id, EntityRelation entityRelation)
{
m_update = ent => EntityRepository.ApplySaveSideEffects(ent, id, entityRelation);
}
public IEntityBase Fetch(EntityId entityId) { throw new NotImplementedException(); }
public void FetchByExpression(Type entityType, Expression expr, IList list, List<Pair<string, bool>> orderBy) { throw new NotImplementedException(); }
public void Update(IEntityBase entity) { m_update(entity); }
}
private class ResponseMock : IResponse
{
public ResponseMock() { Headers = new HttpHeaderDictionary(); }
public IHttpEntity Entity { get { throw new NotImplementedException(); } }
public HttpHeaderDictionary Headers { get; private set; }
public void WriteHeaders() { throw new NotImplementedException(); }
public bool HeadersSent { get { throw new NotImplementedException(); } }
public int StatusCode
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
而且單元測試是:
[Test]
[Factory("YieldPostFlowFolderData")]
public void PostFlowFolder(int id, Uri uri, EntityRelation entityRelation, FlowFolder flowFolder)
{
var entityRepository = new EntityRepositoryMock(id, entityRelation);
var response = new ResponseMock();
var handler = new FlowFolderHandler(response, entityRepository);
var result = handler.Post(flowFolder);
Assert.AreEqual((int)HttpStatusCode.Created, result.StatusCode);
Assert.AreEqual(id, int.Parse(response.Headers["X-Entity-Id"]));
Assert.AreEqual(uri, result.RedirectLocation);
SUC.Utils.AssertDeepEqual(entityRelation, result.ResponseResource);
}
我的問題是我怎麼能寫相同的單元測試(或多或少),無需進行手動嘲笑EntityRepositoryMock
和ResponseMock
使用Rhino.Mocks?
謝謝。
編輯
我手動嘲笑含有不僅因爲他們是手動嘲笑的構造函數。我本來可以添加一個專門的方法PrepareMock
而不是構造函數來確保模擬已準備好......嘲笑。自動模擬,由Rhino.Mocks創建,不會有任何構造函數相關的問題,因爲我會模仿接口而不是具體類型。
我想實施你的意見。第一個問題 - Repeat.Many()的優點是什麼? – mark
接下來,我試圖嘲笑響應。 'responseMock.Expect(m => m.Headers).PropertyBehavior();'不起作用,因爲'Headers'是一個只讀屬性。當'Headers' propery被調用時,我該如何告訴模擬返回某個對象? – mark
對不起,'Repeat.Any()'。它表明指定的返回值應該被返回,即使方法被稱爲多次,你可以通過'Repeat.Once()'調用單個方法調用,所以每次下一次調用模擬方法將返回null而不是返回值返回類型不是void),這適用於'WhenCalled()',它將在每次調用方法時被執行,不僅僅是第一次 – sll