Метод тестирования NUnit с насмешками Rhino не работает - C # - PullRequest
0 голосов
/ 09 ноября 2018

Я создал проект веб-API и реализовал приведенный ниже метод HTTP POST в AccountController и соответствующий метод обслуживания и метод хранилища в 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);
        } 
    }
}

Обратите внимание, что я использовал библиотеку moh Rhino для реализации репозитория mock.

Проблема в том, что это не возвращает ожидаемый результат.Похоже, это не вызывает метод UpdateProfile () в моем классе обслуживания.возвращает NULL.

1 Ответ

0 голосов
/ 09 ноября 2018

Все эти классы тесно связаны с проблемами реализации и должны быть реорганизованы, чтобы быть отделенными и зависимыми от абстракций.

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 в корне композиции приложения.

...