moq
moq copied to clipboard
"Invalid Callback" in NonVoidSetupPhrase.Returns -> ValidateCallbackReturnType is not informative or actionable
.NET version: .NET 6 Test Context: XUnit Moq: 4.8.12
Summary: Following these examples SO: https://stackoverflow.com/questions/45558470/how-do-i-go-about-unit-testing-with-entity-framework-and-moq Doc: https://learn.microsoft.com/en-us/ef/ef6/fundamentals/testing/mocking
'Invalid callback. Setup on method with return type 'EntityEntry<Foo>' cannot invoke callback with return type 'Foo'.'
at Moq.MethodCall.ValidateCallbackReturnType(MethodInfo callbackMethod, Type expectedReturnType)
at Moq.MethodCall.<>c__DisplayClass23_0.<SetReturnComputedValueBehavior>g__ValidateCallback|4(Delegate callback)
at Moq.MethodCall.SetReturnComputedValueBehavior(Delegate valueFactory)
at Moq.Language.Flow.NonVoidSetupPhrase`2.Returns(Delegate valueFunction)
at <test>
Is thrown immediately on execution, with the message
Setup on method with return type 'EntityEntry<Foo>' cannot invoke callback with return type 'Foo'
Expected: Label, name, method, property, field, class, or any other source of the offending issue.
Actual:
Exception Is devoid of any actionable or useful information, as there is no indication or reference to EntityEntry<T>
or EntityEntry<Foo
in this context.
Details:
[Fact]
public void foo()
{
//arrange
var mockFf = new MockDbSet<Foo>(); //Throws immediately on construction
}
with
public class MockDbSet<TEntity> : Mock<DbSet<TEntity>> where TEntity : class
{
public MockDbSet(List<TEntity> dataSource = null)
{
var data = (dataSource ?? new List<TEntity>());
var queryable = data.AsQueryable();
this.As<IQueryable<TEntity>>().Setup(e => e.Provider).Returns(queryable.Provider);
this.As<IQueryable<TEntity>>().Setup(e => e.Expression).Returns(queryable.Expression);
this.As<IQueryable<TEntity>>().Setup(e => e.ElementType).Returns(queryable.ElementType);
this.As<IQueryable<TEntity>>().Setup(e => e.GetEnumerator()).Returns(() => queryable.GetEnumerator());
//Mocking the insertion of entities
this.Setup(_ => _.Add(It.IsAny<TEntity>())).Returns((TEntity arg) => {
data.Add(arg);
return arg;
});
//...the same can be done for other members like Remove
} //Debug call stack is here
}
and Foo
as
public class Foo
{
[Key]
public int Id { get; set; }
public DateTime CreatedDate { get; set; }
[MaxLength(36), Required]
public string CreatedByUserId { get; set; }
public Employee CreatedByUser { get; set; }
public DateTime? ModifiedDate { get; set; }
[MaxLength(36)]
public string ModifiedByUserId { get; set; }
public Employee ModifiedByUser { get; set; }
[Required]
public string Name { get; set; }
[MaxLength(10)]
public string ReferenceNumber { get; set; }
public int? BazId { get; set; }
public Baz Baz { get; set; }
public ICollection<Bar> Bars{ get; set; }
}