2016-09-09 5 views
2

Я пытаюсь издеваться этим методуMoq функция с анонимным типом

Task<TResult> GetResultAsync<TResult>(Func<string, TResult> transformFunc) 

как этого

iMock.Setup(m => m.GetResultAsync(It.IsAny<Func<string, object>>())).ReturnsAsync(new { isPair = false }); 

метод для тестирования делает вызов, проходящий анонимный тип для общего параметра, как это

instance.GetResultAsync(u => new {isPair = u == "something" }) //dont look at the function return because as generic could have diferent implementations in many case 

Moq никогда не соответствует методу GetResultAsync с переданными параметрами.

Я использую Moq 4

+0

Не уверен ... но использование программы установки для этой цели может быть неверным. Если вы создали анонимный объект в своем модульном тесте 'var testObject = {whatevs}', вы можете пропустить установку и проверить ее в конце 'iMock.Verify (x => x.GetResultAsync (testObject))'. Я считаю, что это должно сработать так, как ожидалось. – Will

+2

Как вы хотите, чтобы макет правил? вы ничего не указываете. –

+0

Will and Yacoub благодарит вас за интерес. Я обновил свой вопрос с возвратом этого издевающегося метода. @Will, мне нужно издеваться над поведением метода, потому что он будет использоваться внутри другого метода, который я тестирую. – Deumber

ответ

2

анонимный тип собирается вызвать проблемы. Для этого вам нужен конкретный тип.

Следующий пример работал, когда я изменил

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; 
     } 
    } 
}