我目前正在對一些新的功能我已經加入到我們的ASP.NET項目的一些單元測試(不,這不是測試驅動設計)。我們使用NHibernate框架並使用UnitTest模擬庫FakeItEasy
。FakeItEasy操作參數在單元測試,但仍執行內部操作代碼
我有以下類&方法,我想測試:
public class Round
{
public static Round Create(List<Company> activeCompanies, Period period,
BusinessUser user, BusinessUser systemUser,
ISession session, IEntityQuery entityQuery,
RoundProcessBuilder processBuilder)
{
var round = new Round
{
Processes = new List<Process>();
Period = period,
CreationDate = DateTime.Now,
CreatedBy = user
};
// Save the Round in the DB so we can use it's Id in the Processes:
session.Save(round);
foreach (var company in activeCompanies)
{
var companyData = session.Get<CompanyData>(company.Id);
var processResult =
roundProcessBuilder.Build(
systemUser,
new CreateRoundProcessData(company, round, companyData),
entityQuery,
session);
processResult.HandleProcess(process =>
{
// serviceBus can stay null
process.Create(systemUser, DateTime.Now, session, null);
// No need to save the session here. If something went
// wrong we don't want halve of the processes being saved
round.Processes.Add(process);
// It's all or nothing
});
}
return round;
}
}
我主要是想測試什麼:當我使用這個Round#Create
方法與假設100家活躍的公司,它應該創建100進程,並且每個進程都應該包含。
這是我的單元測試至今:
[TestFixture]
public class RoundTest
{
private BusinessUser _systemUser;
private DateTime _creationDateRound1;
private List<Company> _activeCompanies;
private RoundProcessBuilder _roundProcessBuilder;
private ISession _session;
[SetUp]
public void Setup()
{
_creationDateRound1 = new DateTime(2015, 10, 5);
_systemUser = TestHelper.CreateBusinessUser(Role.Create("systemuser", "test",
Int32.MaxValue));
_activeCompanies = new List<Company>
{
TestHelper.CreateCompany();
};
_roundProcessBuilder = A.Fake<RoundProcessBuilder>();
_session = A.Fake<ISession>();
}
[Test]
public void TestCreateRoundWithoutPreviousRound()
{
var fakeExpectedRound = Round.Create(_activeCompanies, DateTime.Now.ToPeriod(),
_systemUser, _systemUser, _session, null, _roundProcessBuilder);
var fakeExpectedRoundData = RoundProcessData.Create(TestHelper.CreateCompany(),
fakeExpectedRound, new CompanyData());
var fakeExpectedProcess = new Process(_systemUser, null, "processName", null,
fakeExpectedRoundData, "controllerName", null);
var processSuccessResult = new ProcessSuccessResult(fakeExpectedProcess);
A.CallTo(() => _roundProcessBuilder.Build(null, null, null, null))
.WithAnyArguments()
.Returns(processSuccessResult);
A.CallTo(() => processSuccessResult.HandleProcess(A<Action<Process>>.Ignored))
.Invokes((Action<Process> action) => action(fakeExpectedProcess));
var round = Round.Create(_activeCompanies, _ceationDateRound1.ToPeriod(),
_systemUser, _systemUser, _session, null, _roundProcessBuilder);
Assert.AreEqual(_activeCompanies.Count, round.Processes.Count, "Number of processes");
Assert.AreEqual(round.Period.Quarter, Math.Ceiling(_creationDateRound1.Month/3.0m), "Quarter");
Assert.AreEqual(round.Period.Year, round.Year, "Year");
// Test if each of the processes knows the RoundId, have the proper state,
// and are assigned to the systemuser
//foreach (var process in round.Processes)
//{
// var roundProcessData = process.ProcessData as RoundProcessData;
// Assert.IsNotNull(roundProcessData, "All processes should have RoundProcessData-objects as their data-object");
// Assert.AreEqual(roundProcessData.Round.Id, round.Id, "RoundId");
// Assert.AreEqual(process.Phase.State, PhaseState.Start, "Process state should be Start");
// Assert.AreEqual(process.AssignedTo, _systemUser, "AssignedTo should be systemuser");
//}
}
... // More tests
}
我的問題出在下面的代碼:
A.CallTo(() => processSuccessResult.HandleProcess(A<Action<Process>>.Ignored))
.Invokes((Action<Process> action) => action(fakeExpectedProcess));
它給出了一個 「The specified object is not recognized as a fake object.
」 的錯誤。
我之所以有這部分代碼是因爲在以下部位來process
沒有它爲空:
processResult.HandleProcess(process => // <- this was null
{
process.Create(systemUser, DateTime.Now, session, null);
round.Processes.Add(process);
});
PS:我註釋掉額外檢查的foreach在我的單元測試,因爲它最有可能是無論如何,當我嘲笑process
本身時,它是毫無用處的。我的主要測試是如果創建進程並將其添加到基於所給出的活動公司的列表中。
謝謝!我僞造了'ProcessSuccessResult'和'HandleProcess',並且它經過了它。我現在有一個NullReferenceException,但是這是我自己的錯誤,因爲在構造函數/創建方法之一中傳遞null作爲參數。至少我現在可以繼續。看到這個解決方案現在很清楚,但是因爲我對'FakeItEasy'(或者一般的嘲諷)相當陌生,所以我錯過了它。 –