-3

My test case always fails, tell me where I am wrong, Code is below

public class EmployeeService { private readonly IRepository _repository; public EmployeeService(IRepository repository) { _repository = repository; } public bool SaveEmployeeData(Employee employee,bool isSaveNeeded) { bool result = false; try { if (isSaveNeeded) { result= _repository.Save(employee); } } catch (Exception ex) { throw new Exception(); } return result; } } 

And My test case is

[TestMethod()] public void SaveEmployeeDataTest() { var a = new Mock<IRepository>(); a.Setup(s => s.Save(new Employee())).Returns(true).Verifiable(); var result = new EmployeeService(a.Object).SaveEmployeeData(new Employee(), true); Assert.IsTrue(result); } 

It always fails.

1
  • 2
    How does it fail? (And why on earth have you got a catch block which only loses information? Why would you not want the original exception to be thrown?) Commented Jun 26, 2013 at 13:11

3 Answers 3

4

Use It.IsAny<Employee> to setup Save method parameter

a.Setup(s => s.Save(It.IsAny<Employee>())).Returns(true).Verifiable(); 

The reason why your test not working is because you have two different employee instances - one for mock setup, and one which is passed to SaveEmployeeData method call. By default those instances will be compared by reference. Moq waits for Save method call with employee instance, which have reference 13 (e.g). But you are passing another employee with reference 42. Thus setup is never invoked.

You have two more options

  • override Equals and GetHashCode methods of Employee class. Thus Moq will compare employees not by reference, but by business data.
  • use exactly same instance of employee both for mock setup and SaveEmployeeData method call (preferable way)

Usage of same employee instance:

[TestMethod()] public void SaveEmployeeDataTest() { var a = new Mock<IRepository>(); var sameEmployee = new Employee(); a.Setup(s => s.Save(sameEmployee)).Returns(true).Verifiable(); var service = new EmployeeService(a.Object); var result = service.SaveEmployeeData(sameEmployee, true); Assert.IsTrue(result); } 

Overriding equality:

public class Employee { public override bool Equals(object obj) { Employee other = obj as Employee; if (other == null) return false; return this.Id == other.Id; // for example } } 

In this case you can leave your test as is.

Sign up to request clarification or add additional context in comments.

4 Comments

But this would not test whether correct employee instance is used for the method call. This is half testing. If in your code you are not using employee object passed into method, rather creating a new one testcase would never detect it.
@JustCode sorry, didn't get you
Sorry, i overlooked the bottom part of your answer. Its perfect now :-)
@JustCode yep, I just decided that you didn't see my edit with examples of two other possible solutions:)
3

The new Employee() is creating a new employee instance each time, once for the setup of the Save and another for the actual SaveEmployeeData. Because of this, the employee provided never matches the requirements of the setup.

Either use a catch-all approach like lazyberezovsky's answer, or do the following:

[TestMethod()] public void SaveEmployeeDataTest() { var a = new Mock<IRepository>(); var employee = new Employee(); a.Setup(s => s.Save(employee)).Returns(true).Verifiable(); var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true); Assert.IsTrue(result); } 

Because the same Employee instance is used in the setup as in the actual invocation, the setup is matched and the correct result returned.

Comments

1

try this -

[TestMethod()] public void SaveEmployeeDataTest() { var a = new Mock<IRepository>(); var employee = new Employee(); a.Setup(s => s.Save(employee)).Returns(true).Verifiable(); var result = new EmployeeService(a.Object).SaveEmployeeData(employee, true); Assert.IsTrue(result); } 

You need to use the same employee instance in setup as well as method call. This would ensure the verification that your are using the same employee instance which is passed in method and not something created in method or returned from another method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.