tags:

views:

58

answers:

5

Is there a way to know when code is being called from running a test method?

bool MyMethod()
{
    if ( /* are we running a test? */ )
    {
        return true; // otherwise this will fail from the automated build script
    }
    else
    {
        // run the proper code
    } 
}

and please spare me the "this is a really bad idea" comments :)

+1  A: 

Ok, I'll spare you my "this is a really bad idea" comment.

You can just give the method a parameter bool isTestMode.

klausbyskov
What if the method is called through a long call chain? Passing the `isTestMode` parameter down all the way through the call chain seems very intrusive. It's a bad thing to break encapsulation on a single method - doing it on many is much, much worse.
LBushkin
@LBushkin: I totally agree, but since the concept of checking if a method is invoked from a test is a bad idea in the first place I just thought that this approach might lead the OP to a quick "fix" eventhough, granted, it's ugly. But so is checking. The right thing to do is what @Håvard S suggests.
klausbyskov
@klausbyskov: I understand. The OP really should look into using a mocking framework if this is a technique he needs to use in more than one extreme situation.
LBushkin
@LBushkin: Agreed :-)
klausbyskov
+1  A: 

You should check the attribute of calling methods by reflection! I will not mention that this is a bed idea, because you know it as I see ;)

ArsenMkrt
+1  A: 

The approach outlined in your question is a really bad idea.

A cleaner approach if you want a method to behave differently under test than otherwise, is to refactor out an interface with the method, and inject a different implementation at test time.

E.g.:

// Interface whose implementation changes under testing
public interface IChangesUnderTest
{
  void DoesSomething();
}

// Inject this in production
public class ProductionCode : IChangesUnderTest
{
  void DoesSomething() { /* Does stuff */ }
}

// Inject this under test
public class TestCode : IChangesUnderTest
{
  void DoesSomething() { /* Does something else */ }
}
Håvard S
+4  A: 

You recognize this may be a bad idea, but you may not be aware of the alternatives. You should look into mocking frameworks - they can provide a way to inject alternative implementations into your code at runtime in your unit tests. This is an established practice to allow code to behave differently in test and production.

On to the main question.

This depends on the unit test framework you are using. I'm not aware of a specific feature in NUnit (for example) that reports you are in a test. Other frameworks (like MS Test) may very well provide this. However, it's easy to do yourself.

If you're binding to source code, just use a #define directive to conditionally define some variable you can branch on.

If you're binding to a library, I would recommend creating your own class that you use to track whether you are in a unit test or real code, and set that class up in the TestFixture setup method to indicate you are running a test. You could also use the Environment.SetEnvironmentVariable as a way of avoiding writing a special class.

LBushkin
A: 

Here's my suggestion.

Instead of checking the context, just add in some conditional bug code:

#if DEBUG

/* assume you are running in a test environment here */

#endif

This is almost not bad. And if it isn't exactly what you need, you can look into #define-ing "TEST" for when you might want your test code to not execute during regular debugging.

Will