Все эти классы тесно связаны с проблемами реализации и должны быть реорганизованы, чтобы быть отделенными и зависимыми от абстракций.
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);
}
}
Теперь для модульного тестирования в отдельности абстрактные зависимости могут быть смоделированы и введены в испытуемый объект.
Например, следующий тест проверяет AccountService.UpdateProfile
, высмеивая IAccountRepository
и вставляя его в AccountService
.
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);
}
}
Тот же подход можно использовать для тестирования AccountController
. Вместо этого вы должны высмеять IAccountService
и вставить это в контроллер, чтобы проверить действие и подтвердить ожидаемое поведение.
Обязательно зарегистрируйте абстракции и их реализации в контейнере DI в корне композиции приложения.