A member of my team has written a JMockit-based test method that using a Verifications instance to assert a method was invoked on the UUT, which is not mocked, but extends a mocked abstract parent (it happens to be a Hibernate repository). The test passes, but my opinion, based on the JMockit documentation, is that only mocks should be used in a Verifications instance initializer. I think the result is a false negative but my team member insists it's a valid verification call. The test itself is simple, so I've recreated it using contrived objects:
package com.acme.dataacess;
public abstract class AbstractRepository {
public final T list(Class<T> clazz, final Collection<String> keys) {
.....
}
}
package com.acme.module.dataacess
public class FooRepository extends AbstractRepository<Foo> {
public List<Foo> list() {
return getFoos(null);
}
public List<Foo> list(Collection<String> keys) {
return list(Foo.class, keys);
}
}
public class FooRepositoryTest {
#Tested
private FooRepository uut;
#Mocked
private AbstractRepository mockAbstractRepository;
#Test
public void testFoo1() {
// Execute the test.
this.uut.list(null);
// Verify the results.
new Verifications() {
{
// I don't think this is a valid verification, because the goal
// of the test is to assert a delegated method in a non-mocked
// class was invoked.
uut.list(null);
}
};
}
}
Is this a valid JMockit verification?
Related
I am trying to process a custom annotation on a class that implements an external interface that defines a Resource. The setup is the following:
A Resource interface, I can't modify it:
#Path("/v1")
public interface Resource {
#GET
#Path("/foo")
Response foo();
}
An implementation that I can modify:
public class ResourceImpl implements Resource {
#Override
#CustomAnnotation // has Retention.RUNTIME
public Response foo() {
// foo logic
}
}
I've implemented a filter to try and process the #CustomAnnotation on the overriden foo() method:
#Provider
#ServerInterceptor
#Precedence("SECURITY")
public class CustomAnnotationInterceptor implements ContainerRequestFilter {
#Context
ResourceInfo resourceInfo;
#Override
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
// check if the invoked resource method is annotated with #CustomAnnotation and do logic
}
}
However, when I try to get the matched resource class from the ResourceInfo instance, I get the Resource interface, and when I get the matched method, I get the foo() method from the interface which is lacking the #CustomAnnotation. Is there any way around this?
I'm using RESTEasy as an implementation of JAX-RS.
You could implement an interceptor, where you can get hold of the actual resource (method and class) being called. The interceptor should be bound to your annotation using #InterceptorBinding (see 54.2.4 Binding Interceptors to Components).
// Interceptor
#Interceptor
#CustomAnnotation
#Priority(Interceptor.Priority.APPLICATION)
public class CustomAnnotationInterceptor {
#AroundInvoke
public Object interceptCustomAnnotation(InvocationContext ctx) throws Exception {
CustomAnnotation customAnnotation = null;
// The actual method being called
Method method = ctx.getMethod();
if (method != null) {
customAnnotation = method.getAnnotation(CustomAnnotation.class);
}
// ... do stuff with the annotation
return ctx.proceed();
}
}
To get the instance of the class that implements your interface you could use ctx.getMethod().getDeclaringClass() or ctx.getTarget().getClass().getSuperclass().
I have issue while trying to mock method that returns instance of abstract class with Rhino Mocks. Issue is that MammalBase constructor is invoked while stub is created and I would like to avoid that. All source code in question is locked for editing and only tests can be changed.
Eventually, base class is processing something by type attributes in constructor, and throws exception if no adequate attributes are detected. That causes a extensive logging.
My hope is to remove unnecessary logs from tests.
Is it possible to instruct Rhino Mocks not to instantiate return type (MammalBase) when it creates proxy while creating a stub?
Is explicit attribute or type setting possible for return value while Rhino creates stub for method with abstract class instance as return type?
Is avoiding constructor even possible without making stubbed method return interface?
I found that issue does not exist if:
1. Stubbed method returns array like MammalBase[],
2. Stubbed method returns derivate class like "Human" first, since no more constructors of base class are invoked.
Thanks in advance!
(Code sample)
public interface IDetermineMammalByType
{
MammalBase DetermineMammalByType(MammalBase creature);
}
public abstract class MammalBase
{
protected MammalBase()
{
CustomAttribute[] attributes = (CustomAttribute[])Attribute.GetCustomAttributes(this.GetType(), typeof(CustomAttribute));
if (!attributes.Any(x=> x as CustomAttribute != null))
{
//This causes issue
throw new Exception();
}
}
}
[CustomAttribute()]
public class Human : MammalBase { }
[System.AttributeUsage(System.AttributeTargets.Class |
System.AttributeTargets.Struct)]
public class CustomAttribute : System.Attribute
{
public CustomAttribute() { }
}
public class MammalDetector : IDetermineMammalByType
{
public MammalBase DetermineMammalByType(MammalBase creature)
{
//Some logic
return null;
}
}
//TEST
[TestMethod()]
public void DetermineMammalByTypeTest()
{
IDetermineMammalByType myTest = MockRepository.GenerateStub<IDetermineMammalByType>();
var creature = new Human();
//Here it fails while mocking method
myTest.Stub(x => x.DetermineMammalByType(creature)).Return(new Human());
}
Can anyone advise if it is possible to use an expectations/verifications to test that private methods are being called the-right-number-of-times/right-parameters.
The Class under test has been Mocked-Up - with one private method overridden.
Am Testing a public method which calls into a number of private methods.
I wish to know if it is possible to verify the calls to other private methods which will be called when the public method is being executed ?
Some idea of the code/class under test;
public class UnderTest {
public void methodPublic(arg 1){
.....
methodPrivate1(var1);
....
methodPrivate2(var2);
}
private void methodPrivate1(var1){
//do stuff
}
private void methodPrivate2(var1){
//do stuff
}
}
In my test case
#Test
public void stateBasedTestMethod()
{
UnderTest underTest;
new MockUp<UnderTest>() {
#Mock(invocations = 1)
private void methodPrivate2(var1) {
//do nothing in the mocked case
}
};
underTest = new UnderTest();
underTest.methodPublic(arg1);
new Verifications() {{
// Is there a way to test that methodPrivate1 has been called-once/with-expected-arguments
}};
}
Edited in response to the answer from Rogério.
I am using jmockit 1.12
and the Verifications is FAILING as the method using the provided solution is invoking the method twice as I thought from the JMockit documentation.
Failure Trace;
mockit.internal.UnexpectedInvocation: Expected exactly 1 invocation(s) of MyHelperTest$1#method3..., but was invoked 2 time(s)
Included is the full code I am using for this.
As described above - my goal is to mock one of the private methods to do nothing.
And ensure that I can verify that the other private method is called only once.
Thanks in advance and hopefully will get a better understanding if this is possible with Jmockit.
Test Code.
public class MyHelperTest {
#Test
public void testHelper(#Mocked final MyDependent myDependent) {
final MyHelper myHelper;
new MockUp<MyHelper>() {
#Mock(invocations = 1)
private void method3(MyDependent myTable) {
System.out.println("In Mocked Method");
//do nothing in the mocked case
}
};
myHelper = new MyHelper();
myHelper.method1(myDependent);
new Verifications() {{
invoke(myHelper, "method2", myDependent); times = 1;
}};
}
}
Class under test.
public class MyHelper {
public void method1(MyDependent myDependent){
method2(myDependent);
}
private void method2(MyDependent myDependent) {
myDependent.setValue(1);
method3(myDependent);
}
private void method3(MyDependent myDependent) {
myDependent.setValue(2);
}
}
Dependent Class
public class MyDependent {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
It's possible, though not recommended to mock private methods.
Using the Expectations API:
#Tested #Mocked MyHelper myHelper;
#Test
public void testHelper(#Mocked final MyDependent myDependent)
{
new NonStrictExpectations() {{ invoke(myHelper, "method3", myDependent); }};
myHelper.method1(myDependent);
new Verifications() {{ invoke(myHelper, "method2", myDependent); times = 1; }};
}
... where the invoke(...) method is statically imported from class mockit.Deencapsulation.
I noticed that if a method you want to verify is not mocked, when the static block in an Expectations or Verifications instance is executed that the code calls the method that you are trying to mark as expected or verify.
This might explain the extra invocation that you are seeing.
One suggestion: if you are already mocking the class with MockUp (and thus creating an anonymous subclass) so you can override the private method, why not change the access of the overridden private method to protected or public? Then you can create an expectation or verification on it.
You could also provide a public field "public int counter=0;" and have your overridden method increment the counter. Then you can use an assert on it after the test is complete.
I have a class I am unit testing and all I want to do is to verify that the public setter gets called on the property. Any ideas on how to do this?
I don't want to check that a value was set to prove that it was called. I only want to ensure that the constructor is using the public setter . Note that this property data type is a primitive string
This is not the sort of scenario that mocking is designed for because you are trying to test an implementation detail. Now if this property was on a different class that the original class accessed via an interface, you would mock that interface and set an expectation with the IgnoreArguments syntax:
public interface IMyInterface
{
string MyString { get; set; }
}
public class MyClass
{
public MyClass(IMyInterface argument)
{
argument.MyString = "foo";
}
}
[TestClass]
public class Tests
{
[TestMethod]
public void Test()
{
var mock = MockRepository.GenerateMock<IMyInterface>();
mock.Expect(m => m.MyString = "anything").IgnoreArguments();
new MyClass(mock);
mock.VerifyAllExpectations();
}
}
There are 2 problems with what you are trying to do. The first is that you are trying to mock a concrete class, so you can only set expectations if the properties are virtual.
The second problem is the fact that the event that you want to test occurs in the constructor, and therefore occurs when you create the mock, and so occurs before you can set any expectations.
If the class is not sealed, and the property is virtual, you can test this without mocks by creating your own derived class to test with such as this:
public class RealClass
{
public virtual string RealString { get; set; }
public RealClass()
{
RealString = "blah";
}
}
[TestClass]
public class Tests
{
private class MockClass : RealClass
{
public bool WasStringSet;
public override string RealString
{
set { WasStringSet = true; }
}
}
[TestMethod]
public void Test()
{
MockClass mockClass = new MockClass();
Assert.IsTrue(mockClass.WasStringSet);
}
}
I have a service proxy class that makes asyn call to service operation. I use a callback method to pass results back to my view model.
Doing functional testing of view model, I can mock service proxy to ensure methods are called on the proxy, but how can I ensure that callback method is called as well?
With RhinoMocks I can test that events are handled and event raise events on the mocked object, but how can I test callbacks?
ViewModel:
public class MyViewModel
{
public void GetDataAsync()
{
// Use DI framework to get the object
IMyServiceClient myServiceClient = IoC.Resolve<IMyServiceClient>();
myServiceClient.GetData(GetDataAsyncCallback);
}
private void GetDataAsyncCallback(Entity entity, ServiceError error)
{
// do something here...
}
}
ServiceProxy:
public class MyService : ClientBase<IMyService>, IMyServiceClient
{
// Constructor
public NertiAdminServiceClient(string endpointConfigurationName, string remoteAddress)
:
base(endpointConfigurationName, remoteAddress)
{
}
// IMyServiceClient member.
public void GetData(Action<Entity, ServiceError> callback)
{
Channel.BeginGetData(EndGetData, callback);
}
private void EndGetData(IAsyncResult result)
{
Action<Entity, ServiceError> callback =
result.AsyncState as Action<Entity, ServiceError>;
ServiceError error;
Entity results = Channel.EndGetData(out error, result);
if (callback != null)
callback(results, error);
}
}
Thanks
Played around with this a bit and I think I may have what you're looking for. First, I'll display the MSTest code I did to verify this:
[TestClass]
public class UnitTest3
{
private delegate void MakeCallbackDelegate(Action<Entity, ServiceError> callback);
[TestMethod]
public void CallbackIntoViewModel()
{
var service = MockRepository.GenerateStub<IMyServiceClient>();
var model = new MyViewModel(service);
service.Stub(s => s.GetData(null)).Do(
new MakeCallbackDelegate(c => model.GetDataCallback(new Entity(), new ServiceError())));
model.GetDataAsync(null);
}
}
public class MyViewModel
{
private readonly IMyServiceClient client;
public MyViewModel(IMyServiceClient client)
{
this.client = client;
}
public virtual void GetDataAsync(Action<Entity, ServiceError> callback)
{
this.client.GetData(callback);
}
internal void GetDataCallback(Entity entity, ServiceError serviceError)
{
}
}
public interface IMyServiceClient
{
void GetData(Action<Entity, ServiceError> callback);
}
public class Entity
{
}
public class ServiceError
{
}
You'll notice a few things:
I made your callback internal. You'll need to use the InternalsVisisbleTo() attribute so your ViewModel assembly exposes internals to your unit tests (I'm not crazy about this, but it happens in rare cases like this).
I use Rhino.Mocks "Do" to execute the callback whenever the GetData is called. It's not using the callback supplied, but this is really more of an integration test. I assume you've got a ViewModel unit test to make sure that the real callback passed in to GetData is executed at the appropriate time.
Obviously, you'll want to create mock/stub Entity and ServiceError objects instead of just new'ing up like I did.