NUnit Test method with Rhino mocks does not work - C#
up vote
1
down vote
favorite
I have created a web api project and implemented the below HTTP POST method in AccountController and the related service method & repository method in AccountService & AccountRepository respectively.
// 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;
}
}
Also, I wanted to implement a NUNIT test case. Here is the code.
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);
}
}
}
Note that I have used Rhino mocks library to implement the mock repository.
The issue is this does not return the expected output. Looks like it does not trigger the UpdateProfile() method in my service class. it returns NULL.
c# asp.net asp.net-web-api nunit rhino-mocks
add a comment |
up vote
1
down vote
favorite
I have created a web api project and implemented the below HTTP POST method in AccountController and the related service method & repository method in AccountService & AccountRepository respectively.
// 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;
}
}
Also, I wanted to implement a NUNIT test case. Here is the code.
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);
}
}
}
Note that I have used Rhino mocks library to implement the mock repository.
The issue is this does not return the expected output. Looks like it does not trigger the UpdateProfile() method in my service class. it returns NULL.
c# asp.net asp.net-web-api nunit rhino-mocks
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have created a web api project and implemented the below HTTP POST method in AccountController and the related service method & repository method in AccountService & AccountRepository respectively.
// 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;
}
}
Also, I wanted to implement a NUNIT test case. Here is the code.
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);
}
}
}
Note that I have used Rhino mocks library to implement the mock repository.
The issue is this does not return the expected output. Looks like it does not trigger the UpdateProfile() method in my service class. it returns NULL.
c# asp.net asp.net-web-api nunit rhino-mocks
I have created a web api project and implemented the below HTTP POST method in AccountController and the related service method & repository method in AccountService & AccountRepository respectively.
// 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;
}
}
Also, I wanted to implement a NUNIT test case. Here is the code.
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);
}
}
}
Note that I have used Rhino mocks library to implement the mock repository.
The issue is this does not return the expected output. Looks like it does not trigger the UpdateProfile() method in my service class. it returns NULL.
c# asp.net asp.net-web-api nunit rhino-mocks
c# asp.net asp.net-web-api nunit rhino-mocks
asked Nov 9 at 7:42
user9657450
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47
add a comment |
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
accepted
All of these classes are tightly coupled to implementation concerns and should be refactored to be decoupled and dependent on abstractions.
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);
}
}
Now for unit testing in isolation the abstract dependencies can be mocked and injected into the subject under test.
For example the following tests the AccountService.UpdateProfile
by mocking a IAccountRepository
and injecting it into the 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);
}
}
The same approach can be taken for testing the AccountController
. Instead you would mock the IAccountService
and inject that into the controller to test the action and assert the expected behavior.
Make sure to register the abstractions and their implementations with the DI container in the composition root of the application.
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
accepted
All of these classes are tightly coupled to implementation concerns and should be refactored to be decoupled and dependent on abstractions.
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);
}
}
Now for unit testing in isolation the abstract dependencies can be mocked and injected into the subject under test.
For example the following tests the AccountService.UpdateProfile
by mocking a IAccountRepository
and injecting it into the 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);
}
}
The same approach can be taken for testing the AccountController
. Instead you would mock the IAccountService
and inject that into the controller to test the action and assert the expected behavior.
Make sure to register the abstractions and their implementations with the DI container in the composition root of the application.
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
add a comment |
up vote
0
down vote
accepted
All of these classes are tightly coupled to implementation concerns and should be refactored to be decoupled and dependent on abstractions.
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);
}
}
Now for unit testing in isolation the abstract dependencies can be mocked and injected into the subject under test.
For example the following tests the AccountService.UpdateProfile
by mocking a IAccountRepository
and injecting it into the 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);
}
}
The same approach can be taken for testing the AccountController
. Instead you would mock the IAccountService
and inject that into the controller to test the action and assert the expected behavior.
Make sure to register the abstractions and their implementations with the DI container in the composition root of the application.
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
All of these classes are tightly coupled to implementation concerns and should be refactored to be decoupled and dependent on abstractions.
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);
}
}
Now for unit testing in isolation the abstract dependencies can be mocked and injected into the subject under test.
For example the following tests the AccountService.UpdateProfile
by mocking a IAccountRepository
and injecting it into the 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);
}
}
The same approach can be taken for testing the AccountController
. Instead you would mock the IAccountService
and inject that into the controller to test the action and assert the expected behavior.
Make sure to register the abstractions and their implementations with the DI container in the composition root of the application.
All of these classes are tightly coupled to implementation concerns and should be refactored to be decoupled and dependent on abstractions.
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);
}
}
Now for unit testing in isolation the abstract dependencies can be mocked and injected into the subject under test.
For example the following tests the AccountService.UpdateProfile
by mocking a IAccountRepository
and injecting it into the 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);
}
}
The same approach can be taken for testing the AccountController
. Instead you would mock the IAccountService
and inject that into the controller to test the action and assert the expected behavior.
Make sure to register the abstractions and their implementations with the DI container in the composition root of the application.
edited Nov 9 at 16:14
answered Nov 9 at 13:27
Nkosi
107k16113182
107k16113182
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
add a comment |
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
Your solution works. Thank you
– user9657450
Nov 9 at 15:47
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53221609%2fnunit-test-method-with-rhino-mocks-does-not-work-c-sharp%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
It appears that you are expecting the mock to have some sort of behavior without your actually injecting that behavior by setting it up.
– Charlie
Nov 9 at 9:20
I want to run the test for userId 123 with salary 1000 and i should get the test result as 1000. But it shouldn't update the db
– user9657450
Nov 9 at 9:32
Then that api controller needs to be refactored to follow explicit dependency principle. A mock of the service can then be injected directly into the class under test.
– Nkosi
Nov 9 at 11:43
What are you actually trying to test?
– Nkosi
Nov 9 at 11:47