анонимный тип собирается вызвать проблемы. Для этого вам нужен конкретный тип.
Следующий пример работал, когда я изменил
instance.GetResultAsync(u => new {isPair = u == "something" })
в
instance.GetResultAsync(u => (object) new {isPair = u == "something" })
Moq не может соответствовать анонимный тип, и именно поэтому вы получаете null
при вызове.
[TestClass]
public class MoqUnitTest {
[TestMethod]
public async Task Moq_Function_With_Anonymous_Type() {
//Arrange
var expected = new { isPair = false };
var iMock = new Mock<IService>();
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, object>>()))
.ReturnsAsync(expected);
var consumer = new Consumer(iMock.Object);
//Act
var actual = await consumer.Act();
//Assert
Assert.AreEqual(expected, actual);
}
public interface IService {
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc);
}
public class Consumer {
private IService instance;
public Consumer(IService service) {
this.instance = service;
}
public async Task<object> Act() {
var result = await instance.GetResultAsync(u => (object)new { isPair = u == "something" });
return result;
}
}
}
если код вызова GetResultAsync
зависит от использования анонимного типа, то, что вы пытаетесь сделать с вашим испытанием не будет работать с вашей текущей настройкой. Вам, вероятно, потребуется указать конкретный тип метода.
[TestClass]
public class MoqUnitTest {
[TestMethod]
public async Task Moq_Function_With_Concrete_Type() {
//Arrange
var expected = new ConcreteType { isPair = false };
var iMock = new Mock<IService>();
iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, ConcreteType>>()))
.ReturnsAsync(expected);
var sut = new SystemUnderTest(iMock.Object);
//Act
var actual = await sut.MethodUnderTest();
//Assert
Assert.AreEqual(expected, actual);
}
class ConcreteType {
public bool isPair { get; set; }
}
public interface IService {
Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc);
}
public class SystemUnderTest {
private IService instance;
public SystemUnderTest(IService service) {
this.instance = service;
}
public async Task<object> MethodUnderTest() {
var result = await instance.GetResultAsync(u => new ConcreteType { isPair = u == "something" });
return result;
}
}
}
Не уверен ... но использование программы установки для этой цели может быть неверным. Если вы создали анонимный объект в своем модульном тесте 'var testObject = {whatevs}', вы можете пропустить установку и проверить ее в конце 'iMock.Verify (x => x.GetResultAsync (testObject))'. Я считаю, что это должно сработать так, как ожидалось. – Will
Как вы хотите, чтобы макет правил? вы ничего не указываете. –
Will and Yacoub благодарит вас за интерес. Я обновил свой вопрос с возвратом этого издевающегося метода. @Will, мне нужно издеваться над поведением метода, потому что он будет использоваться внутри другого метода, который я тестирую. – Deumber