使用Rhino mocks的NUnit测试方法不起作用-C#



我创建了一个web api项目,并在AccountController中实现了下面的HTTPPOST方法和相关的服务方法&AccountService&AccountRepository。

// WEB API 
public class AccountController : ApiController
{
private readonly IAccountService _accountService;
public AccountController()
{
_accountService = new AccountService();
}
[HttpPost, ActionName("updateProfile")]
public IHttpActionResult updateProfile([FromBody]RequestDataModel request)
{
var response = _accountService.UpdateProfile(request.UserId, request.Salary);
return Json(response);
}
}

public class RequestDataModel
{
public int UserId { get; set; }
public decimal Salary { get; set; }
}
// Service / Business Layer
public interface IAccountService
{
int UpdateProfile(int userId, decimal salary);
}
public class AccountService : IAccountService
{
readonly IAccountRepository _accountRepository = new AccountRepository();
public int UpdateProfile(int userId, decimal salary)
{
return _accountRepository.UpdateProfile(userId, salary);
}
}

// Repository / Data Access Layer
public interface IAccountRepository
{
int UpdateProfile(int userId, decimal salary);
}
public class AccountRepository : IAccountRepository
{
public int UpdateProfile(int userId, decimal salary)
{
using (var db = new AccountEntities())
{
var account = (from b in db.UserAccounts where b.UserID == userId select b).FirstOrDefault();
if (account != null)
{
account.Salary = account.Salary + salary;
db.SaveChanges();
return account.Salary;
}
}
return 0;
}
}

此外,我想实现一个NUNIT测试用例。这是代码。

public class TestMethods
{
private IAccountService _accountService;
private MockRepository _mockRepository;
[SetUp]
public void initialize()
{
_mockRepository = new MockRepository();
}
[Test]
public void TestMyMethod()
{
var service = _mockRepository.DynamicMock<IAccountService>();
using (_mockRepository.Playback())
{
var updatedSalary = service.UpdateProfile(123, 1000);
Assert.AreEqual(1000, updatedSalary);
} 
}
}

请注意,我已经使用Rhino mocks库来实现mock存储库。

问题是这并没有返回预期的输出。看起来它没有触发我的服务类中的UpdateProfile((方法。则返回NULL。

所有这些类都与实现关注点紧密耦合,应该进行重构以解耦并依赖于抽象。

public class AccountController : ApiController  {
private readonly IAccountService accountService;
public AccountController(IAccountService accountService) {
this.accountService = accountService;
}
[HttpPost, ActionName("updateProfile")]
public IHttpActionResult updateProfile([FromBody]RequestDataModel request) {
var response = accountService.UpdateProfile(request.UserId, request.Salary);
return Ok(response);
}
}
public class AccountService : IAccountService {
private readonly IAccountRepository accountRepository;
public AccountService(IAccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
public int UpdateProfile(int userId, decimal salary) {
return accountRepository.UpdateProfile(userId, salary);
}
}

现在,对于隔离的单元测试,可以模拟抽象依赖关系,并将其注入测试对象中。

例如,以下通过模拟IAccountRepository并将其注入AccountService来测试AccountService.UpdateProfile

public class AccountServiceTests {
[Test]
public void UpdateProfile_Should_Return_Salary() {
//Arrange
var accountRepository = MockRepository.GenerateMock<IAccountRepository>(); 
var service = new AccountService(accountRepository);
var userId = 123;
decimal salary = 1000M;
var expected = 1000;
accountRepository.Expect(_ => _.UpdateProfile(userId, salary)).Return(expected);
//Act
var updatedSalary = service.UpdateProfile(userId, salary);
//Assert
Assert.AreEqual(expected, updatedSalary);
}
}

可以采用相同的方法来测试CCD_ 4。相反,您将模拟IAccountService,并将其注入控制器中,以测试操作并断言预期行为。

确保将抽象及其实现注册到应用程序的组合根中的DI容器中。

最新更新