How to divert "non public" method in public class moles - unit-testing

I have a public method that uses a local private method to get data from the Db.
private string SomeMethod(string)
{
...
Doing some operations
...
string data = GetDBData(string);
Doing some operations
...
}
I want to divert/isolate the private method GetDBData(string) using moles so my test will not require the DB.
Obviously, my question is: how to do it?
thank you
Uria
EDIT
Additional information:
i tried to change the method accessors both to public and internal protected,
in both cases i can now see the methods as moles.
BUT when running the test, the original method is still being used and not the detour I've implemented in the PexMethod.

You can try any of the following.
Make the method internal and add an attribute like this to the assembly:
[assembly: InternalsVisibleTo("<corresponding-moles-assembly-name>")]
Change the method access to protected virtual and then use a stub.
Refactor your class so that it gets an interface (IDataAccessObject) as a constructor parameter, SomeMethod being one of the methods of that interface, and then pass a stub of that interface to your class in test methods.

I figured it out
If i have the public MyClass with private SomeMethod
public class MyClass
{
private string SomeMethod(string str){}
}
if you want to mole the SomeMethod method you need to use AllInstances in the test method:
[PexMethod]
SomeMethod(string str)
{
MMyClass.AllInstances.SomeMethod = (instance, str) => { return "A return string"; };
}
notice that the lambda receives an instance parameter as the first parameter. I'm not sure what it's function is.

Related

Dart: testing private methods by accessing mock's property

I'm trying to get a mocked object property. During the initialization, 'child' class is getting a reference to a parent's private function. I'd like to catch this reference during testing to check parent's private method.
This is a simplified example of much more complex code:
class Monkey{
final name;
final Perk _perk;
Monkey('Maya', this._perk){
this._perk.jump = this._jump;
}
void _jump(int a){ // here's the problem, not able to test private method
print('jump ${a}');
}
}
All I want to do is to be able to test private method _jump during testing in mockito. I don't want to change the code.
During test I created
class MockPerk extends Mock implements Perk{}
Monkey(mockedPerk);
What I want to achieve is:
Create Monkey instance with mockedPerk
Capture property _perk.jump in MockedPerk class
Get reference to private _jump method of Moneky's class to be able to test it.
Limitation
Making method public is not an option.
Making method public with #visibleForTesting is not an option
You can capture values passed to setters with verify(mock.setter = captureAny). For example:
var mockedPerk = MockPerk();
var monkey = Monkey('Maya', mockedPerk);
var jump = verify(mockedPerk.jump = captureAny).captured.single as void
Function(int);
jump(5); // Prints: jump 5

Mock class object as parameter of function

I am using junit and mokito to write unit test of my java program.
public MyClass {
private ClassA a;
public void process(ClassB b) {
if(b.method()) a = ClassA.builder().build();
}
}
Now I have write a MockClassA and MockClassB. But I don't know how to :
Pass a MockClassB instantiation to process function
How to verify whether private variable a is set successfully
Can anybody help?
You can use something like:
#Test
public void shouldDoSomething() {
// given
ClassB mock = Mockito.mock(ClassB.class);
Mockito.when(mock.method()).thenReturn(true);
MyClass classUnderTest = new MyClass();
// when
classUnderTest.process(mock);
// then
// Insert assertions
}
However, if your field is private you are unable to test it properly. You should provide a getter for this field if you want to make some assertions against it.
But remember that internal representation of MyClass should not be tested, only the behavior of it so maybe you want to try different approach

what's the effective solution to modify unit test

This question is more like open discussion. I would like to start with an example. Suppose there is one service FooService
public interface IFooService { void Method1(){}}
public class FooService: IFooService { void Method1(){ ... }}
In order to test the service , we write the unit test code like below, no external services
public void TestMethod1(){ ... }
Then suppose in Method1 we need to use another class called AService which inherit from IAService
public interface IAService {void AMethod1(){}}
public class AService : IAService { void AMethod1() {}}
public class FooService : IFooService {
private IAService a;
public FooService (IAService a){ this.a = a;}
void Method1(){ a.AMethod1(); ..... business logic ..... }
}
Then we have to refactor the unit test to mock AService
public void TestMethod1(){
IMockAService aService = MockRepository.StrickMock<IAService>();
.....
}
So when need more external services, we have to add mock service, if some of services changed the logic or add or remove parameters, and so on. If there are 100 test cases, we have to modify all of test cases.
So what's the best solution for mocking increasing external services and effective way to handle any changes of external dependencies for example : add/remove parameters of methods.
thanks
Most times for me it's enough to create the class under test in a Setup method, leaving you with only one place to adapt when the constructor signature changes.
Alternatively you can move construction of the class under test to a private method.
Same goes for methods. Often you can wrap the call to a method under test in a private method. This is especially helpful, if you don't have to set up all passed parameters in every test, but can use defaults, which you might have prepared in your Setup method.

How to mock static member variables

I have a class ClassToTest which has a dependency on ClassToMock.
public class ClassToMock {
private static final String MEMBER_1 = FileReader.readMemeber1();
protected void someMethod() {
...
}
}
The unit test case for ClassToTest.
public class ClassToTestTest {
private ClassToMock _mock;
#Before
public void setUp() throws Exception {
_mock = mock(ClassToMock.class)
}
}
When mock is called in the setUp() method, FileReader.readMemeber1(); is executed. Is there a way to avoid this? I think one way is to initialize the MEMBER_1 inside a method. Any other alternatives?
Thanks!
Your ClassToMock tightly coupled with FileReader, that's why you are not able to test/mock it. Instead of using tool to hack the byte code so you can mock it. I would suggest you do some simple refactorings to break the dependency.
Step 1. Encapsulate Global References
This technique is also introduced in Michael Feathers's wonderful book : Working Effectively with Legacy Code.
The title pretty much self explained. Instead of directly reference a global variable, you encapsulate it inside a method.
In your case, ClassToMock can be refactored into this :
public class ClassToMock {
private static final String MEMBER_1 = FileReader.readMemeber1();
public String getMemberOne() {
return MEMBER_1;
}
}
then you can easily using Mockito to mock getMemberOne().
UPDATED Old Step 1 cannot guarantee Mockito mock safely, if FileReader.readMemeber1() throw exception, then the test will failled miserably. So I suggest add another step to work around it.
Step 1.5. add Setter and Lazy Getter
Since the problem is FileReader.readMember1() will be invoked as soon as ClassToMock is loaded. We have to delay it. So we make the getter call FileReader.readMember1() lazily, and open a setter.
public class ClassToMock {
private static String MEMBER_1 = null;
protected String getMemberOne() {
if (MEMBER_1 == null) {
MEMBER_1 = FileReader.readMemeber1();
}
return MEMBER_1;
}
public void setMemberOne(String memberOne) {
MEMBER_1 = memberOne;
}
}
Now, you should able to make a fake ClassToMock even without Mockito. However, this should not be the final state of your code, once you have your test ready, you should continue to Step 2.
Step 2. Dependence Injection
Once you have your test ready, you should refactor it further more. Now Instead of reading the MEMBER_1 by itself. This class should receive the MEMBER_1 from outside world instead. You can either use a setter or constructor to receive it. Below is the code that use setter.
public class ClassToMock {
private String memberOne;
public void setMemberOne(String memberOne) {
this.memberOne = memberOne;
}
public String getMemberOne() {
return memberOne;
}
}
These two step refactorings are really easy to do, and you can do it even without test at hand. If the code is not that complex, you can just do step 2. Then you can easily test ClassToTest
UPDATE 12/8 : answer the comment
See my another answer in this questions.
UPDATE 12/8 : answer the comment
Question : What if FileReader is something very basic like Logging that needs to
be there in every class. Would you suggest I follow the same approach
there?
It depends.
There are something you might want to think about before you do a massive refactor like that.
If I move FileReader outside, do I have a suitable class which can read from file and provide the result to every single class that needs them ?
Beside making classes easier to test, do I gain any other benefit ?
Do I have time ?
If any of the answers is "NO", then you should better not to.
However, we can still break the dependency between all the classes and FileReader with minimal changes.
From your question and comment, I assume your system using FileReader as a global reference for reading stuff from a properties file, then provide it to rest of the system.
This technique is also introduced in Michael Feathers's wonderful book : Working Effectively with Legacy Code, again.
Step 1. Delegate FileReader static methods to instance.
Change
public class FileReader {
public static FileReader getMemberOne() {
// codes that read file.
}
}
To
public class FileReader {
private static FileReader singleton = new FileReader();
public static String getMemberOne() {
return singleton.getMemberOne();
}
public String getMemberOne() {
// codes that read file.
}
}
By doing this, static methods in FileReader now have no knowledge about how to getMemberOne()
Step 2. Extract Interface from FileReader
public interface AppProperties {
String getMemberOne();
}
public class FileReader implements AppProperties {
private static AppProperties singleton = new FileReader();
public static String getMemberOne() {
return singleton.getMemberOne();
}
#Override
public String getMemberOne() {
// codes that read file.
}
}
We extract all the method to AppProperties, and static instance in FileReader now using AppProperties.
Step 3. Static setter
public class FileReader implements AppProperties {
private static AppProperties singleton = new FileReader();
public static void setAppProperties(AppProperties prop) {
singleton = prop;
}
...
...
}
We opened a seam in FileReader. By doing this, we can set change underlying instance in FileReader and it would never notice.
Step 4. Clean up
Now FileReader have two responsibilities. One is read files and provide result, another one is provide a global reference for system.
We can separate them and give them a good naming. Here is the result :
// This is the original FileReader,
// now is a AppProperties subclass which read properties from file.
public FileAppProperties implements AppProperties {
// implementation.
}
// This is the class that provide static methods.
public class GlobalAppProperties {
private static AppProperties singleton = new FileAppProperties();
public static void setAppProperties(AppProperties prop) {
singleton = prop;
}
public static String getMemberOne() {
return singleton.getMemberOne();
}
...
...
}
END.
After this refactoring, whenever you want to test. You can set a mock AppProperties to GlobalAppProperties
I think this refactoring would be better if all you want to do is break the same global dependency in many classes.
Powermock core provides a convenient utility method that could be used for this purpose.
Add powermock-core to your project.
testImplementation group: 'org.powermock', name: 'powermock-core', version: '2.0.9'
FileReader fileReader = mock(FileReader.class);
Whitebox.setInternalState(ClassToMock.class, "MEMBER_1", fileReader);
Whitebox.setInternalState is just a convenient method to set the value of a field using reflection. So it could be used along with any Mockito tests.

How to mock HttpClientCertificate?

I am trying to unit test an action filter I wrote. I want to mock the HttpClientCertificate but when I use MOQ I get exception. HttpClientCertificate doesnt have a public default constructor.
code:
//Stub HttpClientCertificate </br>
var certMock = new Mock<HttpClientCertificate>();
HttpClientCertificate clientCertificate = certMock.Object;
requestMock.Setup(b => b.ClientCertificate).Returns(clientCertificate);
certMock.Setup(b => b.Certificate).Returns(new Byte[] { });
This is the most awkward case of creating unit testable systems in .NET. I invariable end up adding a layer of abstraction over the component that I can't mock. Normally this is required for classes with inaccessible constructors (like this case), non-virtual methods or extension methods.
Here is the pattern I use (which I think is Adapter pattern) and is similar to what MVC team has done with all the RequestBase/ResponseBase classes to make them unit testable.
//Here is the original HttpClientCertificate class
//Not actual class, rather generated from metadata in Visual Studio
public class HttpClientCertificate : NameValueCollection {
public byte[] BinaryIssuer { get; }
public int CertEncoding { get; }
//other methods
//...
}
public class HttpClientCertificateBase {
private HttpClientCertificate m_cert;
public HttpClientCertificateBase(HttpClientCertificate cert) {
m_cert = cert;
}
public virtual byte[] BinaryIssuer { get{return m_cert.BinaryIssuer;} }
public virtual int CertEncoding { get{return m_cert.CertEncoding;} }
//other methods
//...
}
public class TestClass {
[TestMethod]
public void Test() {
//we can pass null as constructor argument, since the mocked class will never use it and mock methods will be called instead
var certMock = new Mock<HttpClientCertificate>(null);
certMock.Setup(cert=>cert.BinaryIssuer).Returns(new byte[1]);
}
}
In your code that uses HttpClientCertificate you instead use HttpClientCertificateBase, which you can instantiate like this - new HttpClientCertificateBase(httpClientCertificateInstance). This way you are creating a test surface for you to plug in mock objects.
The issue is that you need to specify constructor parameters when creating the mock of the HttpClientCertificate.
var certMock = new Mock<HttpClientCertificate>(ctorArgument);
The bad news is that the ctor for HttpClientCertificate is internal and takes in an HttpContext, so it probably won't work.
Unless you want to write more code to make the class "Testable" I suggest you use Typemock Isolator, Unless specified otherwise it looks for the first c'tor available - public, internal or private and fake (mocks) it's parameters so you won't have to.
Creating the fake object is as simple as:
var fakeHttpClientCertificate = Isolate.Fake.Instance<HttpClientCertificate>();
Another alternative is to use the free Microsoft Moles framework. It will allow you to replace any .NET method with your own delegate. Check out the link as it gives an example that is pretty easy to understand. I think you'll find it much nicer than adding layers of indirection to get HttpClientCertificate into a testable state.