0

I have an API as below:

 private readonly IMyService _myService;
    public MyController(IMyService myService)
    {
        _myService = myService;
    }

    //GET: api/values
    [HttpGet]

    public MyOutput<MyEntity> Get(string f, string o)
    {
        var fItems = JsonConvert.DeserializeObject<Dictionary<string, string>>(f);
        var oItems = GetDictionaryFromStr(o ?? "");

        var myInput = new MyInput<MyEntity>()
        {
            PredicateDictionary = fItems,
            OrderByDictionary = oItems
        };

        var result = _myService.Search(myInput);

        return result;
    }

It works well. Now, I want to write a unit test for my API, using Moq and Xunit;. I want to set the expected values of result, then mock my DIs and call the controller, What I expect is that the return value of controller and my results be equal. but I don't know why result in var result = api.Get(f, o); is null after returns from controller. Is there anything wrong whit my test?

    [Fact]
    public void Should_ReturnResult_When_CallingMyApi()
    {
        //Arrange
        var f = "{'Currency':'UR'}";
        var o = "+Amount";

        var fItems = JsonConvert.DeserializeObject<Dictionary<string, string>>(f);
        var oItems = GetDictionaryFromStr(o ?? "");


        var baseServiceMock = new Mock<IMyService>();
        baseServiceMock 
            .Setup(x => x.Serach(It.Is<MyInput<MyEntity>>
                (i => i.PredicateDictionary== fItems
                 && i.OrderByDictionary == oItems
                 && i.Paging == pagingItems
                )))
            .Returns(new MyOutput<MyEntity>()
            {
                OrderByDictionary = oItems,
                PredicateDictionary = fItems
            });

        var api = new MyController(baseServiceMock.Object);



        //Act
        var result = api.Get(f, o);


        ////Assert
        Assert.Equal(result.PredicateDictionary, fItems);
        Assert.Equal(result.OrderByDictionary, oItems);
    }

Update: Also I changed the baseServiceMock, with and without the It.Is. In case of It.Is I added

            baseServiceMock
            .Setup(x => x.Search(It.Is<MuInput<MyEntity>>
                (i => i.PredicateDictionary.Keys == fItems.Keys
                && i.PredicateDictionary.Values == fItems.Values
                && i.OrderByDictionary.Keys == oItems.Keys
                && i.OrderByDictionary.Values == oItems.Values
                && i.Paging == pagingItems
               )))
            .Returns.....
4
  • The issue lies with trying to get equality using the It.IS<> and collections. while troubleshooting you could use It.IsAny<MuInput<MyEntity>>. Also you can try using CollectionAssert Commented May 9, 2016 at 7:24
  • But I don't want to skip validation. IsAny will skip, doesn't? I exactly want to tell to Setup() that return MyOutput(...) for exactly these input parameters. Commented May 9, 2016 at 7:48
  • 1
    You misunderstand me. I was saying to use IsAny while debugging the problem. That is just so you can check that a result is actually being returned. Once that is confirmed then you can change it back to look at the other possibility that your asserts are not comparing the collections properly. With your current filter are you getting past the Act to your Asserts? Commented May 9, 2016 at 11:28
  • After Mocking the dependency to the controller, the api is null, so, result is null o, and the assert is not passed. Commented May 9, 2016 at 11:39

1 Answer 1

1

The problem was comparing two objects in SetUp(). So I Edited the code as below:

 .Setup(x => x.Find(It.Is<MuInput<MyEntity>>
                (i => i.PredicateDictionary.First().Key == "Currency"
                && i.PredicateDictionary.First().Value == "CU_UR"
                && i.OrderByDictionary.First().Key == "Amount"
                 && i.OrderByDictionary.First().Value == "Asc")))
Sign up to request clarification or add additional context in comments.

1 Comment

So you are saying that this works? If it does, glad you were able to find a solution to your problem. Happy coding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.