-3

I have two methods like below.

public bool IsSuccess()
{
   // Some logi
}

public bool ShouldSendLogic()
{
  var status = IsSuccess();
  if(status)
  {
    SendInvoice();
   // do some operation
  }
 return status;
}

Now I am writing integration/unit tests. I can call the ShouldSendLogic but I want to ensure SendInvoice is not called by setting the Success as false. (Just for negative case). How to write test case for this scenario, please help me with a code for this.

Jasmine
  • 5,186
  • 16
  • 62
  • 114
  • does `SendInvoice` cause any side-effect that you can measure? – Sam I am says Reinstate Monica Aug 01 '16 at 03:31
  • @SamIam: Yes, this logic shouldn't be executed when status is false as per above logic – Jasmine Aug 01 '16 at 03:32
  • but does it cause any side effects? What does it do? – Sam I am says Reinstate Monica Aug 01 '16 at 03:33
  • @SamIam: Doesn't have side effects it sends invoice which shouldn't happen and also do some logging in database. – Jasmine Aug 01 '16 at 03:36
  • Moq (or some other mocking framework )it. Check this out: http://stackoverflow.com/questions/347818/using-moq-to-determine-if-a-method-is-called. It's almost a duplicate of the question you asked. – Ash Aug 01 '16 at 03:40
  • 1
    Sending an invoice sounds like a side-effect to me. Why not make sure that you have a way to receive a sent invoice and then check to make sure the invoice is not sent? Alternatively, why not trust the return value of the method? Without a good [mcve] that shows clearly what's going on, it's impossible to offer any sort of real, specific answer. Fact is, when you call a method, you don't generally get to monitor, never mind dictate, what that method does. If you insist on the unit test depending on this behavior (or lack of it), you'll have to build something like that into the code. – Peter Duniho Aug 01 '16 at 03:40
  • @AshwinNair: Chetta I am not using Mock, secondly, I use only the normal Test in Visual Studio, si that solution isn't quite appropriate to my problem. Also, I found another verify method thats not being useful. – Jasmine Aug 01 '16 at 03:49
  • @PeterDuniho: Mate, I just need a basic unit test method to ensure this simple method is not called, how would you write code. I dont need you to focus on logic, mate – Jasmine Aug 01 '16 at 03:50
  • @SamIam: I am not introducing MOQ, could u please help me with syntax – Jasmine Aug 01 '16 at 04:16
  • @AshwinNair: da chetta, I am not introducing MOQ, could u please help me with syntax – Jasmine Aug 01 '16 at 04:16
  • I don't understand. You can either mock `SendInvoice()` and `verify` whether it's called or not. Or (and I do not recommend this at all) you'd have to modify your code to set an accessible flag (boolean property) when `SendInvoice()` is called so you can check it's value in the test. Maybe post your test and we can have a look at it. – Ash Aug 01 '16 at 04:46
  • @AshwinNair: edda chetta, I could achieve, but I get this error Expected invocation on the mock at least once, but was never performed – Jasmine Aug 01 '16 at 05:25
  • Post your test. The error is telling you that you've set up your mock to expect the method to be called at least once and that it was actually never called. Change your expectation count to `Times.Never` or change your test so it's actually called. – Ash Aug 01 '16 at 05:32
  • @AshwinNair: da, it should be called, I can't make never lol. That would be deceiving to my employer – Jasmine Aug 01 '16 at 05:33
  • @all: Can anybody explain, why this question was downrated? For me it's a legitimate question and a very typical problem, testing "beginners" are facing. – mrAtari Aug 03 '16 at 09:21

1 Answers1

-2

You can change the ShouldSendLogic() to accept status as parameter bool ShouldSendLogic(bool status). In this way, ShouldSendLogic can be tested for positive and negative cases.

Another approach is to have IsSuccess() part of an interface and inject the dependency to the class that has ShouldSendLogic(). The IsSuccess() result can be modified by mockup classes in unit test environment and ShouldSendLogic() can be tested for different status values.

class MyClass
{

    ISomeInterface _interfaceObj;

    public MyClass(ISomeInterface interfaceObj)
    {
        _interfaceObj = interfaceObj;
    }

    public bool ShouldSendLogic()
    {
        var status = _interfaceObj.IsSuccess();
        if (status)
        {
            SendInvoice();
            // do some operation
        }
        return status;
    }
}

Edit

By separating the code that checks for success to an interface, you can now create a "mock" object in your unit tests, where YOU can decide what the value of IsSuccess() should be.

e.g.

public class MockSuccessClass : ISomeInterface
{
    public bool IsSuccess { return true; }
}

And then in your "Arrange" section of your unit test, you can create an instance of the MockSuccessClass and pass it to the SUT.

You don't have to use Moq, but it would save time if you let Moq create your Mock classes for you.

failedprogramming
  • 2,532
  • 18
  • 21
KDR
  • 478
  • 6
  • 19