我有两个测试。首次测试工作正确。第二次测试看起来像第一次测试。但是,当我进行第二次测试时,我得到例外。
第一次测试:
public void GetCurrentBalance_Should_getting_rigth_balanse()
{
// Arrange
double balance = 10;
var mocks = new MockRepository();
IUnitOfWork unitOfWork = mocks.Stub<IUnitOfWork>();
unitOfWork.Stub(svc => svc.AccountRepository.Get()).Return(new List<Account> {new Account { Balance = balance }});
AccountService accountService = new AccountService(unitOfWork);
// Act
mocks.ReplayAll();
var result = accountService.GetCurrentBalance();
//Assert
Assert.AreEqual(balance, result);
}
第二次测试:
public void WithdrawMoney_Balance_should_decrease_when_money_been_withdrawn()
{
// Arrange
double balance = 10;
var mocks = new MockRepository();
IUnitOfWork unitOfWork = mocks.Stub<IUnitOfWork>();
unitOfWork.Stub(svc => svc.AccountRepository.Get()).Return(new List<Account> { new Account { Balance = balance } });
AccountService accountService = new AccountService(unitOfWork);
// Act
mocks.ReplayAll();
var result = accountService.WithdrawMoney(1); // this line is different
//Assert
Assert.AreEqual(balance - 1, result);
}
我的部分服务:
public class AccountService : BaseService, IAccountService
{
public AccountService(IUnitOfWork unitOfWork)
: base(unitOfWork)
{
}
public double WithdrawMoney(double amountOfMoney)
{
var currentBalance = GetCurrentBalance();
if (currentBalance < amountOfMoney)
{
throw new BusinessLayerException("error!");
}
var lastAccount = GetLastAccount();
if (lastAccount == null)
{
throw new BusinessLayerException("error!");
}
lastAccount.Balance -= amountOfMoney;
unitOfWork.AccountRepository.Update(lastAccount);
unitOfWork.Save();
return lastAccount.Balance;
}
public double GetCurrentBalance()
{
var lastAccount = GetLastAccount();
if (lastAccount == null)
{
return 0;
}
return lastAccount.Balance;
}
private Account GetLastAccount()
{
var lastAccount = unitOfWork.AccountRepository.Get().FirstOrDefault();
return lastAccount;
}
}
我得到以下调用堆栈:
Rhino.Mocks.Exceptions.ExpectationViolationException : IUnitOfWork.get_AccountRepository(); Expected #1, Actual #2.
at Rhino.Mocks.MethodRecorders.UnorderedMethodRecorder.DoGetRecordedExpectation(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.MethodRecorders.MethodRecorderBase.GetRecordedExpectation(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.DoMethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.ReplayMockState.MethodCall(IInvocation invocation, MethodInfo method, Object[] args)
at Rhino.Mocks.MockRepository.MethodCall(IInvocation invocation, Object proxy, MethodInfo method, Object[] args)
at Rhino.Mocks.Impl.Invocation.Actions.RegularInvocation.PerformAgainst(IInvocation invocation)
at Rhino.Mocks.Impl.RhinoInterceptor.Intercept(IInvocation invocation)
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.Proxies.IUnitOfWorkProxy2936ffa6dea844258ad88f7a7e99dbc0.IUnitOfWork.get_AccountRepository()
at Service.AccountService.GetLastAccount() in AccountService.cs: line 90
at Service.AccountService.WithdrawMoney(Double amountOfMoney) in AccountService.cs: line 61
at ServiceTest.AccountServiceTest.WithdrawMoney_Balance_should_decrease_when_money_been_withdrawn() in AccountServiceTest.cs: line 48
答案 0 :(得分:3)
遵循Rhione模拟测试的以下规则
使用Rhino Mocks只需按照Mock Object下的步骤进行操作:
1.Create mock by:mockrepository.CreateMock();
2.记录您的表达:在记录块中。
3.call ReplayAll告诉犀牛模拟你已完成录制
4.MOST IMP。 STEP:在这里调用预期的方法,例如:mockMyRhinoImplementation.HelloRhinoMocks(“ABC”)
注意:必须传递您记录的相同参数,否则它将再次抛出ExpectationViolationException。
5.Call VerifyAll();
所以,两个测试之间的差异是一个方法有争论而另一个方法没有...尝试使用如下所示
double number = 1;
var result = accountService.WithdrawMoney(number);
答案 1 :(得分:1)
我通过更改第二个测试来解决问题。我换了一行: 从:
IUnitOfWork unitOfWork = mocks.Stub<IUnitOfWork>();
为:
IUnitOfWork unitOfWork = mocks.DynamicMock<IUnitOfWork>();
但在我看来,这对我的问题来说是一个糟糕的解决方案。