Modify byte code to make a method return true - classloader

I have class file has a method like this:
public boolean validate(String str) {}
There're lots of codes inside this validate method, but I only want to make it always return true or false. Can someone point me out how to modify a class file to achieve this?

RULE override rtn
CLASS Foo
METHOD validate
IF true
DO RETURN true
ENDRULE
http://www.jboss.org/byteman

Are you trying to unit test this code and force an answer without caring about the conditions? If that is the case, then you are looking for "Mocking" frameworks. In Java, I can think of Mockito and EasyMock off of the top of my head.
Relatedly, you can use PowerMock (works in tandem with either of the above Mocking frameworks) to dynamically change classes (such as final classes/methods, static methods, and even private pieces of classes). PowerMock actually can change the byte code when necessary. Check under its classloading folders.
I've never considered it, but it might be possible to use any of them within non-test code, but they may require finagling to avoid JUnit dependencies (such as JUnit Runner). Again, I have never thought about it, so I never thought through the implications.
At the very least, you can probably look through PowerMockito to see how they change the byte code.
If you just want to unit test, then it's extremely easy and you probably don't need to worry about the byte code.
public class SomeClass {
public boolean validate(String s) {
// tons of logic
}
}
Test (using Mockito with JUnit 4 (drop the #Test attribute for JUnit 3)):
private final MyClassBeingTested testClass = new MyClassBeingTested();
#Test
public void testMyCodeWithSomeClass() {
SomeClass some = mock(SomeClass.class);
when(some.validate(anyString())).thenReturn(eq(true));
// whenever it uses "some.validate()", with any
// string, then it will return true
testClass.useSomeClass(some);
// assert whatever conditions you want
// if you care to ensure that it called validate:
// note: times(1) is implied if not supplied, but times(0), times(2), etc.
// could be used ("never()" exists as a synonym for times(0))
verify(some, times(1)).validate(anyString());
}

It can only return true or false, according to the method signature provided.
Can you make a wrapper class that delegates calls to the original and overrides the behaviour that you require, instead of trying to manipulate the bytecode?

The simplest way to modify the byte code is to decompile the class or get a copy of the source code. Change the code and compile it. Put the new version earlier in the classpath or replace the original in the jar. This way you have changed the method.
You can change it at runtime, but that is 100x harder. ;)

Related

Can method call be tested without Mockito.verify?

If i need to test if a method within class under test has been called or not, can it be done without Mockito (or any mocking tool for that matter)?
Reason asking is that wherever i read about Mockito and similar tools, it says one should never mock CUT but its dependencies (that part is clear).
So, if thats the case then there are only 2 options left:
there is some other way of testing it without mocking
or
the fact the method was called should not be tested itself but some side effect or methods return value
For example (trivial and non-realworld), class MyClass can have 2 methods: A() and B(). A conditionay calls B based on some internal state.
After arranging state & acting by calling A() we want to assert that B() was called.
Either its not possible without mocking the whole CUT or 2 methods like this in a single class are always SRP violation smell and call for redesign where B() should actually be (mocked) dependency of MyClass CUT.
So, whats correct?
Usually I tend to not even use spies, instead I prefer to write my code in a way that for any class I write:
I test only non-private methods, since they're entry points into the class under test. So, in your example, if a() calls b(), maybe b() should be be private and, as a consequence, should not be tested. To generalize, a() is something that a class "can do" (a behavior), so I test the behavior, and not the method itself. If this behavior internally calls other things - well, its an internal matter of that class, if possible I don't make any assumptions on how does the class work internally, and always prefer "white-box" testing.
I only test "one" non-private method in a test.
All the methods should return something (best option) or at least call dependencies, or change internal state of the object under test. The list of dependencies is always clean-to-understand, I can't instantiate the object of CUT without supplying it a list of dependencies. For example, using constructor dependency injection is a good way of doing this. I mock only dependencies indeed, and never mock / spy CUT. Dependencies are never static but injected.
Now with these simple rules, the need to "test if a method within class under test has been called or not" basically can boil down to one of the following:
you're talking about private method. In this case - don't test it, test only public things.
The method is public - in this case you explicitly call it in unit test, so its irrelevant.
Now lets ask why do you want to test this if a method within CUT has been called or not?
If you want to make sure that it changed something. If this "something" is within the class - in other words, its internal state has changed, check in test that the change is indeed done in the state by calling another method that allows to query the state
If this "something" is a code that is managed by dependency, create a mock of this dependency and verify that it was called with the expected parameters.
Take a look at the Mockito Documentation (https://static.javadoc.io/org.mockito/mockito-core/3.0.0/org/mockito/Mockito.html#13)
When using a Spy you can 'replace' a method in the same class that is under test.
#ExtendWith(MockitoExtension.class)
public class Test {
class MyClass {
public void a() {
b();
}
public void b() {
}
}
#Test
public void test() {
MyClass testClass = new MyClass();
MyClass spy = Mockito.spy(testClass);
Mockito.doNothing().when(spy).b();
spy.a();
Mockito.verify(spy, Mockito.times(1)).b();
}
}
So whether that is something that should be done is a different question ;)
I think it highly depends on what method B() is actually doing and whether that is supposed be part of MyClass in the first place.
Either its not possible without mocking the whole CUT
In this case we do not mock the whole CUT only the method you do not want to be called.
Reason asking is that wherever i read about Mockito and similar tools, it says one should never mock CUT but its dependencies (that part is clear).
I believe this statement is not entirely accurate in correlation with spying.
The whole point of spying in my eyes is to use it on the class under test. Why would one want to spy on a dependecy that is not even supposed to be part of the test in the first place?

Is it bad practice to unit test a method that is calling another method I am already testing?

Consider you have the following method:
public Foo ParseMe(string filepath)
{
// break up filename
// validate filename & extension
// retrieve info from file if it's a certain type
// some other general things you could do, etc
var myInfo = GetFooInfo(filename);
// create new object based on this data returned AND data in this method
}
Currently I have unit tests for GetFooInfo, but I think I also need to build unit tests for ParseMe. In a situation like this where you have a two methods that return two different properties - and a change in either of them could break something - should unit tests be created for both to determine the output is as expected?
I like to err on the side of caution and be more wary about things breaking and ensuring that maintenance later on down the road is easier, but I feel very skeptical about adding very similar tests in the test project. Would this be bad practice or is there any way to do this more efficiently?
I'm marking this as language agnostic, but just in case it matters I am using C# and NUnit - Also, I saw a post similar to this in title only, but the question is different. Sorry if this has already been asked.
ParseMe looks sufficiently non-trivial to require a unit test. To answer your precise question, if "you have a two methods that return two different properties - and a change in either of them could break something" you should absolutely unit test them.
Even if the bulk of the work is in GetFooInfo, at minimum you should test that it's actually called. I know nothing about NUnit, but I know in other frameworks (like RSpec) you can write tests like GetFooInfo.should be_called(:once).
It is not a bad practice to test a method that is calling another method. In fact, it is a good practice. If you have a method calling another method, it is probably performing additional functionality, which should be tested.
If you find yourself unit testing a method that calls a method that is also being unit tested, then you are probably experiencing code reuse, which is a good thing.
I agree with #tsm - absolutely test both methods (assuming both are public).
This may be a smell that the method or class is doing too much - violating the Single Responsibility Principle. Consider doing an Extract Class refactoring and decoupling the two classes (possibly with Dependency Injection). That way you could test both pieces of functionality independently. (That said, I'd only do that if the functionality was sufficiently complex to warrant it. It's a judgment call.)
Here's an example in C#:
public interface IFooFileInfoProvider
{
FooInfo GetFooInfo(string filename);
}
public class Parser
{
private readonly IFooFileInfoProvider _fooFileInfoProvider;
public Parser(IFooFileInfoProvider fooFileInfoProvider)
{
// Add a null check
_fooFileInfoProvider = fooFileInfoProvider;
}
public Foo ParseMe(string filepath)
{
string filename = Path.GetFileName(filepath);
var myInfo = _fooFileInfoProvider.GetFooInfo(filename);
return new Foo(myInfo);
}
}
public class FooFileInfoProvider : IFooFileInfoProvider
{
public FooInfo GetFooInfo(string filename)
{
// Do I/O
return new FooInfo(); // parameters...
}
}
Many developers, me included, take a programming by contract approach. That requires you to consider each method as a black box. If the method delegates to another method to accomplish its task does not matter, when you are testing the method. But you should also test all large or complicated parts of your program as units. So whether you need to unit test the GetFooInfo depends on how complicated that method is.

Dependency Injection and Unit test this constructor

I have a constructor and a property in the class:
private IMyCollectionObjects _myCollectionObjects;
public MyClassConstructor(string message)
{
_myCollectionObjects = MyCollection.GetCollectionObejects(message);
}
With as much detail can you please help me understand how to unit test this constructor
and GetCollectionObjects method?
How do I completely decouple the
classes? You can give the answer
using any IoC, I want to
understand the concept.
Thank you.
Dependencies on static members such as GetCollectionObjects are difficult to test because you can't replace its implementation at runtime. This means that you cannot fully isolate an instance of MyClassConstructor from the implementation details of GetCollectionObjects. Without isolation of the test target, it can't really be considered a unit test.
See here for further discussion of static dependencies.
You can refactor this code to be fully decoupled (and thus fully testable):
private readonly IMyCollectionObjects _myCollectionObjects;
public MyClassConstructor(IMyCollectionObjects myCollectionObjects)
{
_myCollectionObjects = myCollectionObjects;
}
This bubbles the knowledge of how to turn a message into a collection right out of MyClassConstructor, making the class simpler, more cohesive, and less coupled.
For of all, unit testing is all about unitary testing, that is, one thing at a time.
With as much detail can you please help me understand how to unit test this constructor and GetCollectionObjects method?
First things first, have you unit tested your MyCollection class?
If not, you should begin with it, as your MyClassConstructor class depends on it, that is the basis of dependency injection. Otherwise, how can you manage to know if the results you're getting are right or wrong? You won't be able to test and be sure that it works flawlessly.
How do I completely decouple the classes? You can give the answer using any IoC, I want to understand the concept.
I my humble point of view, you must have a clear reason to make an object dependant of another using dependency injection. Once you make an object depend on another, it makes no sense, in my opinion, to decouple them. One way of decoupling might be to use Unity Application Block of Enterprise Library.
Unit test this constructor
You generally only need to check for three things while testing such a constructor.
That the constructor doesn't return a null value;
That the instance it returns is of the expected type;
That the object you expect to be instantiated through its dependency is actually instiated.
[TestCase("message")]
public void DependentConstructorTest(string message) {
MyClassConstructor myclass = new MyClassConstructor(message);
Assert.IsNotNull(myclass);
Assert.IsInstanceOf(typeof(MyClassConstructor), myclass);
Assert.IsNotNull(myclass.MyCollection); // Where MyCollection represents the property that
// exposes the instance created of the object from
// which your MyClassConstructor class depends on.
}
Note: This test is written using NUnit attributes and assertion methods. Use whatever else you like.
Here is roughly what you would need to do (with some assumptions).
Assuming MyCollection is a static class and GetCollectionObjects parses a string and returns an IMyCollectionObjects, you would first need to make MyCollection non-static, and pass it through the constructor as well. Static classes/methods used in a class create a tight coupling, more or less by definition.
Now you would be constructing the class passing a message string and a MyCollection. Your constructor uses the two in combination to populate a member variable of type IMyCollectionObjects. In order to ensure that this happens as expected, you will need a way to examine the result from outside the class (i.e. a public method). So you will need a property getter that exposes _myCollectionObjects.
Now you just need to call this contructor from one or more tests, and check the property after construction to ensure parsing the string into a collection was successful.
Note that this is really more of an integration test than a discrete unit test. You are really testing that the parsing was successful. If the class represented here is really what you intend to test, the test would really just be checking that GetCollectionObjects was called. The result of that call is really irrelevant, because you would (presumably) have a separate test or set of tests that ensure that the method GetCollectionObjects on MyCollection works as expected.

Unit-testing a simple collection class

Consider the following class:
public class MyIntSet
{
private List<int> _list = new List<int>();
public void Add(int num)
{
if (!_list.Contains(num))
_list.Add(num);
}
public bool Contains(int num)
{
return _list.Contains(num);
}
}
Following the "only test one thing" principle, suppose I want to test the "Add" function.
Consider the following possibility for such a test:
[TestClass]
public class MyIntSetTests
{
[TestMethod]
public void Add_AddOneNumber_SetContainsAddedNumber()
{
MyIntSet set = new MyIntSet();
int num = 0;
set.Add(num);
Assert.IsTrue(set.Contains(num));
}
}
My problem with this solution is that it actually tests 2 methods: Add() and Contains().
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other. Of course, Contains() now servers as a thin wrapper for List's Contains() which shouldn't be tested in itself, but what if it changes to something more complex in the future? Perhaps a simple "thin wrap" method should always be kept for testing purposes ?
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo or PrivateObject) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems if someday the internal list is replaced by some other collection (maybe C5).
Is there a better way to do this?
Are any of my arguments against the above implementations flawed?
Thanks in advance,
JC
Your test seems perfectly OK to me. You may have misunderstood a principle of unit testing.
A single test should (ideally) only test one thing, that is true, but that does not mean that it should test only one method; rather it should only test one behaviour (an invariant, adherence to a certain business rule, etc.) .
Your test tests the behaviour "if you add to a new set, it is no longer empty", which is a single behaviour :-).
To address your other points:
Theoretically, there could be a bug in both, that only manifests in scenarios where they are not called one after the other.
True, but that just means you need more tests :-). For example, add two numbers, then call Contains, or call Contains without Add.
An alternative approach might suggest mocking out or exposing (possibly using InternalsVisibleTo) the private _list member and have the test inspect it directly, but that could potentially create test maintainability problems[...]
Very true, so don't do this. A unit test should always be against the public interface of the unit under test. That's why it's called a unit test, and not a "messing around inside a unit"-test ;-).
There are two possibilities.
You've exposed a flaw in your design. You should carefully consider if the actions that your Add method is executing is clear to the consumer. If you don't want people adding duplicates to the list, why even have a Contains() method? The user is going to be confused when it's not added to the list and no error is thrown. Even worse, they might duplicate the functionality by writing the exact same code before they call .Add() on their list collection. Perhaps it should be removed, and replaced with an indexer? It's not clear from your list class that it's not meant to hold duplicates.
The design is fine, and your public methods should rely on each other. This is normal, and there is no reason you can't test both methods. The more test cases you have, theoretically the better.
As an example, say you have a functions that just calls down into other layers, which may already be unit tested. That doesn't mean you don't write unit tests for the function even if it's simply a wrapper.
In practice, your current test is fine. For something this simple it's very unlikely that bugs in add() and contains() would mutually conspire to hide each other. In cases where you are really concerned about testing add() and add() alone, one solution is to make your _list variable available to your unit test code.
[TestClass]
public void Add_AddOneNumber_SetContainsAddedNumber() {
MyIntSet set = new MyIntSet();
set.add(0);
Assert.IsTrue(set._list.Contains(0));
}
Doing this has two drawbacks. One: it requires access to the private _list variable, which is a little complex in C# (I recommend the reflection technique). Two: it makes your test code dependent on the actual implementation of your Set implementation, which means you'll have to modify the test if you ever change the implementation. I'd never do this for something as simple as a collections class, but in some cases it may be useful.

How do mock frameworks work?

If I was to write a mocking library, how would this work (in other words, how do "they work?)?
One of the things which I wonder is that you are always setting expectations so really you need to compare the expectation to what the method does at runtime, so I assume reflection (resolving types at runtime) is required.
Also, when using the term "mock object", is the object stubbed out or would it be an object with pre-set expectations?
When I think how I would write my own implementation of a framework/technique, like mock objects, I realise how much I really know (or don't know) and what I would trip up on: If the mock object is pre-programmed to return set expectations and you don't call the actual real object, then wouldn't the result always be the same? Eg:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs()
{
var fake = Isolate.Fake.Instance<ClassToIsolate>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, " abc")).WithExactArguments().WillReturn(10);
// MethodReturnInt will return 50 when called with arguments 3, "xyz"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "xyz")).WithExactArguments().WillReturn(50);
Assert.AreEqual(10, fake.MethodReturnInt(3, "abc"));
Assert.AreEqual(50, fake.MethodReturnInt(3, "xyz"));
}
Wouldn't this always return true?
The idea with mocking frameworks is to mock out dependencies, and not the actual classes under test. For your example, your test will always return true, because really you're only testing the mocking framework and not your actual code!
A real world mock would look more like this:
[TestMethod, Isolated]
public void FakeReturnValueByMethodArgs() {
var fake = Isolate.Fake.Instance<DependencyClass>();
// MethodReturnInt will return 10 when called with arguments 3, "abc"
Isolate.WhenCalled(()=> fake.MethodReturnInt(3, "abc")).WithExactArguments().WillReturn(10);
var testClass = new TestClass(fake);
testClass.RunMethod();
// Verify that the setup methods were execute in RunMethod()
// Not familiar with TypeMock's actual method to do this...
IsolatorExtensions.VerifyInstanceWasCalled(fake);
// Or assert on values
Assert.AreEqual(10, testClass.AProperty);
}
Notice how the mock is passed into the TestClass and a method run on it.
You can read The Purpose of Mocking to get a better idea of how mocking works.
Update: Explanation why you're testing only the mocking framework:
What you've done is create a method MethodReturnInt with the mocking framework using Isolate.WhenCalled(). When you call MethodRecturnInt in the Assert, the code will run the delegate () => fake.MethodReturnInt() and return 10. The mocking framework is effectively creating a method (albeit dynamically) that would look something like this:
public void MethodReturnInt(int value, string value2) {
Assert.Equal(3, value);
Assert.Equal("abc", value2);
return 10;
}
It's a bit more complicated than that, but this is the general idea. Since you never run any code other than the creation of 2 methods and then asserts on those two methods, you're not testing your own code and therefore only testing the mocking framework.
Yes, it will always return true. Mock objects should be used when the class under test requires another class implementation that you don't want to involve in the test run. This is most useful when it's a class that uses interfaces with multiple implementations, or there are complex/expensive/external services that you don't want to set up.
In the above code, you're mocking the class that you're "testing".
Another way of thinking about it is that the mock behaviours you record are black-box (implementation) assertions, where Assert.* are white-box (api) assertions.
You have the right idea. You will often find that they have a couple of modes of operation. If you're worried about your method not getting called or it not getting called in the right order there is quite often a 'strict' mode that causes the mock framework to throw an exception if the method isn't called by the end of the test, or is called with the wrong parameters etc.
Most of the frameworks have thought of those sorts of issues so you just need to find out how to configure it for your scenario.
One way to look at how mock system work is just look at times when you need an object but you don't want to use the real class but instead want it to give you some specific kind of data that it wouldn't (or won't do so reliably). So if you see:
Assert.IsTrue(myLogic.IsNoon(time))
you can see how the assert would want the time object to always be noon. . . well you can't do that with a real object reliably. So you need a stand-in. You can make a fake class just for the test, but that's sort of heavy. Mock frameworks are a shortcut.