3

I have a class Class1, which has a constructor and few methods. For these methods I'm writing the unit test cases using MSTest. The class looks like this.

class Class1
{
    Order order = new Order(); // there is an class Order
    public Class1(Order _order)
    {
        order = _order;
    }
    public virtual async Task<bool> GetData()
    {
        if(order != null)
        {
            //do something
        }
        else
        {
            // do something else
        }
    }
}

Now, I have to write 2 test cases for this GetData() method, when which tests if block and one which tests the else block. I was able to test the if block successfully, but not able to test the else block. The test method which I'm trying to write is as below.

[TestMethod()]
public void GetDataTest()
{
    Order order = new Order();
    order = null;
    var mockService = new Mock<Class1>(order)
    {
        CallBase = true
    };
    var result = await mockService.Object.GetData(); // error thrown from here
    Assert.IsFalse(result);
}

What I'm trying to do is set the order object to null and pass the null object to the constructor.But this is throwing some error "Ambiguous match found". Clearly passing the null value is not working here. So can anyone tell me any other work around to test the else block.

PS: I need to test both if and else block so that it is included in the code coverage.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
CrazyCoder
  • 2,194
  • 10
  • 44
  • 91
  • "But this is throwing some error "Ambiguous match found"" - please provide the *exact* error message, and explain whether this is at compile time or execution time, and where in the code it's occurring. Ideally provide a [mcve] so we can just copy/paste/compile and see the issue. – Jon Skeet Jul 04 '18 at 05:18
  • @DaisyShipton This is an execution time error. The exact error message is "system.reflection.ambiguousmatchexception: ambiguous match found." I have edited the code to show from where the error is thrown. – CrazyCoder Jul 04 '18 at 05:24
  • Okay, if it's an exception then please include a complete stack trace - that will help to clarify what's trying to match something with reflection. – Jon Skeet Jul 04 '18 at 05:29

3 Answers3

2

If your code is real then actually there is no need to mock service under test.

This works just fine:

[TestMethod]
public async Task GetDataTest()
{
    //Arrange
    Order order = null;
    var c1 = new Class1(order);

    //Act
    var result = await c1.GetData();

    //Assert
    Assert.IsFalse(result);
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472
Nicklaus Brain
  • 884
  • 6
  • 15
  • Thanks for the reply. In my case I do not have use mock. But what if , I have a method call in GetData() and I have to mock that calling method, so I will have to use mock object. What can I do in that case? – CrazyCoder Jul 04 '18 at 07:10
  • 1
    Check the following code (using nsubstitute): https://paste.ubuntu.com/p/Xcyn9FRvrM/ – Nicklaus Brain Jul 04 '18 at 07:52
0

Well, the unit test case and the code which you have shared doesn't have any issue

Except

You are not returning a task, and the error "ambiguous match found" looks like coming from inside the code which is written inside else block.

Try to change your GetData() method as :

public virtual async Task<bool> GetData()
        {
            TaskCompletionSource<bool> ts = new TaskCompletionSource<bool>();
            if (order != null)
            {
                //do something
                ts.SetResult(true);
            }
            else
            {
                // do something else
                ts.SetResult(false);
            }
            return await ts.Task;
        }
Anupam Singh
  • 1,158
  • 13
  • 25
0

You must return from "GetData()"

public virtual async Task<bool> GetData()    
{
    if(order != null)
    {
        //do something
    }
    else
    {
        // do something else
    }
//return task here with await keyword;
}
zacs
  • 132
  • 6