How to write test to current method? I use jUnit 4.
public void setImage() {
if(conditionOne){
myView.setImageOne();
} else {
myView.setImageTwo();
}
}
You need to write two tests to cover both the scenarios as below:
import org.junit.Test;
public class SetImageTest {
#Test
public void testSetImageForConditionOne() {
//write test to make conditionOne true
}
#Test
public void testSetImageForElseCondition() {
//write test to make conditionOne false
}
}
Okay... there is a flaw in the way you wrote this method. There is something called testable code. Here is a link (how to write testable code and why it matters) that discusses testable code.
The method you wrote above is non-deterministic. Which means the method can exhibit different behaviors on different runs, even if it has the same input. In your case you have no input.
Currently, your original method is based on the environment of the method and not the input. This practice can make it very difficult and in some cases impossible to write proper test for your code.
So this is how you want it to look like...
public void setImage(boolean conditionOne) {
if(conditionOne){
myView.setImageOne();
} else {
myView.setImageTwo();
}
}
Now that the test is deterministic your either going to have to test the variables that are in the environment, or have a return statement.
So (adding a return statement) you can do this.
public static void setImage(boolean conditionOne, type myView) {
if(conditionOne){
myView.setImageOne();
} else {
myView.setImageTwo();
}
return myView;
}
Now your test can look something like this
public class SetImageTest {
#Test
public void testSetImage() {
type myViewOrig;
//define myViewOrig
type myView1;
//define myView1
type myView2;
//define myView2
assertEquals(setImage(<true>, type myViewOrig), myView1);
assertEquals(setImage(<false>, type myViewOrig), myView2);
}
}
Or you can just test the myView object after running your setImage method.
Related
I'm new to unit testing, and I'm trying to test that a method has been called. The method in question doesn't return anything.
public void example (boolean foo) {
if (foo) {
processFoo(foo);
}
else if (foo==false) {
processSomethingElse(foo);
}
}
I want to be able to test that the processFoo method is being called, but I don't know how to do that.
If mocking is required, then I have to use JMockit. Thanks!
Sorry I'm a little late to the party, but I have a couple of ideas for you.
First, you mention that one option is to use JMockit--that's great as it gives you a lot of flexibility. If you use JMockit, then the visibility of your processFoo() method doesn't much matter. Let's see what that might look like:
public class Subject {
public void example (boolean foo) {
if (foo) {
processFoo(foo);
}
else if (foo==false) {
processSomethingElse(foo);
}
}
private void processFoo(boolean b) {
System.out.println("b = " + b);
}
private void processSomethingElse(boolean bb) {
System.out.println("bb = " + bb);
}
}
So, one caveat with this option, though is that I'm going to assume processFoo() is a method on your test subject and I'm going to use a partial mock to change the test subject--not something I really like to do, but this is an example. In general, it is best to only mock the dependencies of your test subject rather than behavior of the test subject itself--you have been advised! Note that the processFoo() method of the test subject is private. I'm going to substitute a method for the test with JMockit's partial mocking and the visibility of that new method does not have to match the original.
import static org.assertj.core.api.Assertions.assertThat;
import mockit.Mock;
import mockit.MockUp;
import mockit.integration.junit4.JMockit;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(JMockit.class)
public class SubjectTest {
private Subject testSubject = new Subject();
private boolean processFooCalled = false;
#Before
public void setup() {
new MockUp<Subject>() {
#Mock
public void processFoo(boolean b) {
processFooCalled = true;
};
};
}
#Test
public void should_call_processFoo() {
testSubject.example(true);
assertThat(processFooCalled).isTrue();
}
#Test
public void should_not_call_processFoo() {
testSubject.example(false);
assertThat(processFooCalled).isFalse();
}
}
Ok, so that was the first option. It's actually a little easier if you forget JMockit for this one, assuming you are able to subclass your test subject and override the processFoo() method:
public class Subject {
public void example (boolean foo) {
if (foo) {
processFoo(foo);
}
else if (foo==false) {
processSomethingElse(foo);
}
}
protected void processFoo(boolean b) { // NOTE: protected access here!
System.out.println("b = " + b);
}
private void processSomethingElse(boolean bb) {
System.out.println("bb = " + bb);
}
}
So, in this case, the strategy is simply to subclass your test subject and replace the implementation of the method you wish to observe being called. It might look like this:
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class SubjectTest2 {
private Subject testSubject = new TestableSubject();
private boolean processFooCalled = false;
#Test
public void should_call_processFoo() {
testSubject.example(true);
assertThat(processFooCalled).isTrue();
}
#Test
public void should_not_call_processFoo() {
testSubject.example(false);
assertThat(processFooCalled).isFalse();
}
class TestableSubject extends Subject {
#Override
protected void processFoo(boolean b) {
processFooCalled = true;
}
}
}
Give it a whirl. Hope it helps!
You could use a counter variable in your class and increment it whenever the method is called, or use a print statement. If you don't have access to the processFoo method, a simple approach would be to do this at the time that processFoo is called in another method, if that's the only place where it can possibly be called.
For example:
public static int processFooCalls = 0;
// ...
public void example (boolean foo) {
if (foo) {
processFoo(foo);
processFooCalls += 1;
// and/or
System.out.println("processFoo method was called");
}
// ...
}
public static void main (String[] args) {
// main routine here...
System.out.println("'processFoo' was called " + processFooCalls + " times.");
}
If processFoo can be called elsewhere, and you need to consider this possibility as well, then you'll need to have access to the processFoo code in order to do this, e.g.:
void processFoo( boolean b ) {
// increment number of times processFoo was called here, and/or print, as follows
processFooCalls += 1;
System.out.println("called processFoo method!");
/* some functionality */
}
Looking at the JMockit documentation, you will need the following tools:
Static Mocking: http://jmockit.github.io/tutorial/BehaviorBasedTesting.html#staticPartial
Invocation Counts: http://jmockit.github.io/tutorial/BehaviorBasedTesting.html#constraints
Combining the two in a test (my syntax may be a little off since I'm more accustomed to Mockito, but the concept should hold):
#Test
public void someTestMethod(#Mocked({"processFoo"}) final ExampleClass exampleclass)
{
new Expectations() {{
exampleclass.processFoo(); times = 1;
}};
exampleclass.example(true);
}
This should mock the processFoo method, leaving everything else intact, and checks to make sure it is called exactly once.
Don't consider doing any kind of partial mocking for this, all you're doing in that case is ensuring that if you want to refactor your code your tests will fail. There is a mantra in unit testing - "never test private methods".
What you should be doing is testing that the method you call conforms to the behaviour you want to see. In this case what happens when foo is true is what's important, not that it calls processFoo. So if foo is true you want to be testing that the action processFoo carries out is true and nothing else.
Let's say I have two implementations of a search algorithm that return the same result for the same input. They both implement the same interface.
How can I use a single [TestClass] for testing both implementations, rather then create two test files with eventually the same logic ?
Can I tell MSUnit to launch one of the tests twice with different constructor parameter?
Perhaps I should (n)inject it somehow ?
Use an abstract test class:
[TestClass]
public abstract class SearchTests
{
private ISearcher _searcherUnderTest;
[TestSetup]
public void Setup()
{
_searcherUnderTest = CreateSearcher();
}
protected abstract ISearcher CreateSearcher();
[TestMethod]
public void Test1(){/*do stuff to _searcherUnderTest*/ }
// more tests...
[TestClass]
public class CoolSearcherTests : SearcherTests
{
protected override ISearcher CreateSearcher()
{
return new CoolSearcher();
}
}
[TestClass]
public class LameSearcherTests : SearcherTests
{
protected override ISearcher CreateSearcher()
{
return new LameSearcher();
}
}
}
You've tagged your question with NUnit, but you ask about MSTest. What you are asking about can be achieved with parameterized test fixtures in NUnit. I am not familiar enough with MSTest to suggest an equivalent approach there, and a quick search indicates that MSTest may not have this feature.
In NUnit you parameterize the test fixture by applying multiple [TestFixture(...)] attributes to the fixture class with different parameters. These parameters will be passed to the fixture constructor.
Since there are limits on the types of parameter that can be passed, you'll probably need to pass a string in specifying the algorithm, then in the constructor assign the delegate or object that provides the search algorithm to a member field which is used in the tests.
For example:
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace MyTests
{
public static class SearchAlgorithms
{
public static int DefaultSearch(int target, IList<int> data)
{
return data.IndexOf(target);
}
public static int BrokenSearch(int target, IList<int> data)
{
return 789;
}
}
[TestFixture("forward")]
[TestFixture("broken")]
public class SearchTests
{
private Func<int, IList<int>, int> searchMethod;
public SearchTests(string algorithmName)
{
if (algorithmName == "forward")
{
this.searchMethod = SearchAlgorithms.DefaultSearch;
return;
}
if (algorithmName == "broken")
{
this.searchMethod = SearchAlgorithms.BrokenSearch;
}
}
[Test]
public void SearchFindsCorrectIndex()
{
Assert.AreEqual(
1, this.searchMethod(2, new List<int> { 1, 2, 3 }));
}
[Test]
public void SearchReturnsMinusOneWhenTargetNotPresent()
{
Assert.AreEqual(
-1, this.searchMethod(4, new List<int> { 1, 2, 3 }));
}
}
}
I'd rather have two different [TestMethod] in one [TestClass] each testing only one implementation: this way a failing test will always correctly point you which implementation went wrong.
If you are using NUnit you can pass through a variable declared in an attribute
http://www.nunit.org/index.php?p=testCase&r=2.5.6
if you use something like:
[TestCase(1)]
[TestCase(2)]
public void Test(int algorithm)
{
//..dostuff
}
if will run once for 1, once for 2, uses the same setup/teardown too :)
There isn't an equivalent in MSTest however you can fudge it somewhat as explained here:
Does MSTest have an equivalent to NUnit's TestCase?
I can't say I'm extremely happy with this approach, but here's what I ended up doing. I then went to look for a better approach and found this question. This approach meets the criteria, 1) I'm using MS Test, 2) I write the test logic only 1 time, 3) I can tell which implementation failed (and double clicking on the test will take me to the right test class).
This approach uses a base class to contain all the actual test logic, and then a derived class for each implementation (I have 3) that sets the specific implementation on the base interface and overrides the base test methods.
[TestClass]
public abstract class SearchTestBase
{
protected ISearcher Searcher { get; set; }
[TestMethod]
public virtual void Find_Results_Correct()
{
// Arrange (code here)
// Act (single line here)
var actual = Searcher.Results(input);
// Assert
}
}
(different file...)
[TestClass]
public class FastSearcherTest : SearcherTestBase
{
[TestInitialize]
public void TestInitialize()
{
Searcher = new FastSearcher();
}
[TestMethod]
public override void Find_Results_Correct()
{
base.Find_Results_Correct();
}
}
(different file...)
[TestClass]
public class ThoroughSearcherTest : SearcherTestBase
{
[TestInitialize]
public void TestInitialize()
{
Searcher = new ThoroughSearcher();
}
[TestMethod]
public override void Find_Results_Correct()
{
base.Find_Results_Correct();
}
}
So what I don't like about this approach is that every time I want to add a test I need to go to each of the test files and override the new test method. What I do like are the 3 requirements you had. If I need to change a test, I change the logic in just one place.
The advantage I see to this solution over the similar one of having a single method called by two tests is that I don't have to repeat the code for setting up the right implementation. In this solution you have a single line that calls the base.TestName(), and not two lines, one to set the Searcher and another to call the test. The Visual Studio also makes writing this much faster... I just type, "override" and get a list of choices. Auto complete writes the rest for me.
Clarifications based on my testing.
The accepted answer (to use an abstract class) works as long as the abstract class and concrete classes are in the same assembly.
If you desire to have the abstract class and concrete classes in different assemblies, the approach mentioned by KarlZ, unfortunately seems to be necessary. Not sure why this is the case. In this scenario, the TestExplorer will not show TestMethod.
Also, the accepted answer uses concrete classes nested within the abstract class. This does not appear to be a requirement.
Test with MSTestV2 (1.1.17), VS2017.
Here are sample classes used.
Assembly 1
[TestClass]
public abstract class SampleExternal
{
[TestMethod]
public void SampleTest01()
{
Assert.IsTrue(false, this.GetType().Name);
}
}
Assembly 2
[TestClass]
public abstract class Sample
{
[TestMethod]
public void SampleTest01()
{
Assert.IsTrue(false, this.GetType().Name);
}
[TestClass]
public class SampleA : Sample
{
}
}
[TestClass]
public class SampleB : Sample
{
}
[TestClass]
public class SampleC : SampleExternal
{
}
[TestClass]
public class SampleD : SampleExternal
{
}
using these, the test for SampleA and SampleB will execute (and fail by design), but SampleC & SampleD will not.
I am a Software Engineer in Test, and I am trying to write code that can replace production side method so that test can execute those instead. Basically, I do not want to modify production code for testability.
Here is a simple scenario:
public class Foo {
public static void foo() {
printA();
}
public static void printA() {
System.out.println("A");
}
public static void printB() {
System.out.println("B");
}
}
public class Foobar {
public Foobar() {
}
public void test() {
Foo.foo();
}
public static void main(String[] args) {
//Try changing the method here
new Foobar().test();
}
}
As you can see, when the main executes, it will print "A" since it calls the method printA on static method foo(). Now on runtime, is there a way I can inject or modify such that foo will call printB instead of printA?
Thank you for all the help!
Look at AspectJ.
It provides advices, which can be used to execute some code around a method (before and after its execution), including bypassing the call to original method altogether and returning some arbirary value
If you're just doing this for testing out classes, you could use a mocking framework to mock the classes on the server. I like Mockito.
You can do it yourself using the java reflection api, or you can you use a tool like PowerMock.
I want to back up my application's database before replacing it with the test fixture. I'm forced to use Junit3 because of Android limitations, and I want to implement the equivalent behavior of #BeforeClass an #AfterClass.
UPDATE: There is now a tool (Junit4Android) to get support for
Junit4 on Android. It's a bit of a kludge but should work.
To achieve the #BeforeClass equivalent, I had been using a static variable and initializing it during the first run like this, but I need to be able to restore the database after running all the tests. I can't think of a way of detecting when the last test has run (since I believe there is no guarantee on the order of test execution.)
public class MyTest extends ActivityInstrumentationTestCase2<MainActivity> {
private static boolean firstRun = true;
#Override
protected void setUp() {
if(firstRun) {
firstRun = false;
setUpDatabaseFixture();
}
}
...
}
From the junit website:
Wrapped the setUp and tearDown method in the suite.This is for the
case if you want to run a single YourTestClass testcase.
public static Test suite() {
return new TestSetup(new TestSuite(YourTestClass.class)) {
protected void setUp() throws Exception {
System.out.println(" Global setUp ");
}
protected void tearDown() throws Exception {
System.out.println(" Global tearDown ");
}
};
}
If you would like to run only one setUp and tearDown for all the
testcase, make a suite and add testClass to it and pass the suite
object in TestSetup constructor.But I think there is not much usage
for this,and in a way it is violating JUnit philosophy.
Recently, I was looking for a similar solution too. Fortunately, in my case after the JVM exits after the last test is run. So I was able to achieve this by adding a JVM shutdown hook.
// Restore database after running all tests
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
restoreDatabase();
}
});
hope this helps.
I would suggest avoiding these kind of dependencies where you need to know the order in which tests are run. If all you need is to restore a real database that was replaced by setUpDatabaseFixture() probably you solution comes from the use of a RenamingDelegatingContext. Anyway, if you can't avoid knowing when the last test was run, you can use something like this:
...
private static final int NUMBER_OF_TESTS = 5; // count your tests here
private static int sTestsRun = 0;
...
protected void tearDown() throws Exception {
super.tearDown();
sTestsRun += countTestCases();
if ( sTestsRun >= NUMBER_OF_TESTS ) {
android.util.Log.d("tearDow", "*** Last test run ***");
}
}
Isn't this (dealing elegantly with data, so you don't have to worry about restoring it) what testing with mock objects are for? Android supports mocking.
I ask as a question, since I've never mocked Android.
In my experiences, and from this blog post, when the Android tests are made into a suite and run by the InstrumentationTestRunner - ActivityInstrumentationTestCase2 is an extension of ActivityTestCase which is an extendsion of InstrumentationTestCase - they are ordered alphabetically using android.test.suitebuilder.TestGrouping.SORT_BY_FULLY_QUALIFIED_NAME, so you can just restore you DB with a method that is the lowes in the alphabet out of your test names, like:
// underscore is low in the alphabet
public void test___________Restore() {
...
}
Note:
You have to pay attention to inherited tests, since they will not run in this order. The solution is to override all inherited test and simply call super() from the override. This will once again have everything execute alphabetically.
Example:
// Reusable class w only one time setup and finish.
// Abstract so it is not run by itself.
public abstract class Parent extends InstrumentationTestCase {
#LargeTest
public void test_001_Setup() { ... }
#LargeTest
public void test_____Finish() { ... }
}
/*-----------------------------------------------------------------------------*/
// These will run in order shown due to naming.
// Inherited tests would not run in order shown w/o the use of overrides & supers
public class Child extends Parent {
#LargeTest
public void test_001_Setup() { super.test_001_Setup(); }
#SmallTest
public void test_002_MainViewIsVisible() { ... }
...
#LargeTest
public void test_____Finish() { super.test_____Finish(); }
}
I have a method and wish to test it with different values. My question is: how can I write a JUnit test that would test the same method with different values?
You can take a look at parametrized tests like in example.
You can also use theories which is more convenient in a lot of cases.
JUnit4 supports parameterized tests for just this purpose.
See this tutorial.
I suggest you create a different unit test for each one of your (overloaded) function definitions, because arguably you are testing in fact different functions. For instance:
class MainClass {
public void method( int param) {... }
public void method( String param) { ...}
}
class MainClassTest {
#Test
public void methodIntTest() {
//call method(int)
}
#Test
public void methodStringTest() {
//call method(String)
}
}