Skip to content

Instantly share code, notes, and snippets.

@marcusoftnet
Created May 10, 2011 17:49
Show Gist options
  • Save marcusoftnet/964983 to your computer and use it in GitHub Desktop.
Save marcusoftnet/964983 to your computer and use it in GitHub Desktop.
Get Property substituting
// This is the interface i want to Subsitute
public interface ICustomerRepository
{
IQueryable<Customer> All { get; } // This property
IQueryable<Customer> AllIncluding(params Expression<Func<Customer, object>>[] includeProperties);
Customer Find(int id);
void InsertOrUpdate(Customer customer);
void Delete(int id);
void Save();
}
/////////////////////////////////////////
// First try
/////////////////////////////////////////
[Test]
public void get_customer_by_name_queries_by_name()
{
// Arrange
var c = CreateTestCustomer();
var request = new GetCustomerRequest { CallId = CALLID, CustomerName = c.Name };
var customerList = CreateTestCustomers(c);
ICustomerRepository rep = Substitute.For<ICustomerRepository>();
rep.All.ReturnsForAnyArgs(customerList.AsQueryable());
// Act
var response = service.GetCustomerByName(request);
// Assert
Assertions.AssertOKResponse(response, CALLID);
rep.ReceivedWithAnyArgs().All;
// This last line gives me the following compilation error:
// Only assignment, call, increment, decrement, and new object expressions can be used as a statement
}
//////////////////////////////
// Second try
//////////////////////////////
[Test]
public void get_customer_by_name_queries_by_name()
{
// Arrange
var c = CreateTestCustomer();
var request = new GetCustomerRequest { CallId = CALLID, CustomerName = c.Name };
var customerList = CreateTestCustomers(c);
ICustomerRepository rep = Substitute.For<ICustomerRepository>();
rep.All.ReturnsForAnyArgs(customerList.AsQueryable());
// Act
var response = service.GetCustomerByName(request);
// Assert
Assertions.AssertOKResponse(response, CALLID);
rep.All.ReceivedWithAnyArgs();
// This compiles but gives the following error when I run the test:
// NSubstitute.Exceptions.NotASubstituteException : NSubstitute extension methods like .Received() can only be called on objects created using Substitute.For<T>() and related methods.
// Which I understand since the All-property isn't substituted
// How shall I do this?
}
@dtchepak
Copy link

First you'll need to make sure you inject the ICustomerRepository rep into the service (it's the class under test right?).

To satisfy the compiler, Line 31 should be:

var all = rep.Received().All;

The all variable can be ignored, but if you want to call the All getter the C# compiler needs you to assign it to something. It's not pretty, but we have to place nice with the compiler. :)

That said, I would avoid asserting the getter was called, because it doesn't tell you if or how the result of the call was used. With Line 24 you are stubbing out that rep.All will return customerList.AsQueryable(), so I would look at a way of asserting that customerList has been used to do whatever is needed in the response. That way you have implicitly checked the rep.All getter is called, but you have done that by specifying how the types should work together, which should make it easier to change if you refactor how it works later. For example, you could adjust the Arrange statements to get the customerList from somewhere else, but the assertions would stay the same.

You can also change Line 24 to rep.All.Returns(customerList.AsQueryable()) (rather than ReturnsForAnyArgs), as there are no arguments that need to be ignored.

Hope this helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment