I have written an Azure durable function in F# and am trying to write unit tests, following the guidelines at https://learn.microsoft.com/en-us/azure/azure-functions/durable/durable-functions-unit-testing. I have attempted to use Foq to create a mock instance of the abstract class DurableOrchestrationContextBase, but that fails with the following error:
System.TypeLoadException : Method 'set_InstanceId' on type 'Mock.DurableOrchestrationContextBase1953fcc2-be15-41fc-850c-5a5813aace89' from assembly 'Foq.Dynamic, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is overriding a method that is not visible from that assembly.
The error relates to this property:
public virtual string InstanceId { get; internal set; }
Further investigation shows that Foq is able to mock non-virtual, non-abstract properties with internal setters on abstract C# classes, but can't cope with such properties if they are virtual.
Is there any way to mock such a class in an F# test? Rolling my own implementation would be awkward in this case, as DurableOrchestrationContextBase is a large class with many members that would need implementing.
In the end I worked around this issue by switching to NSubstitute, which is capable of mocking this kind of class. NSubstitute's API is relatively easy to use from F#, since (unlike in Moq, for example) you can configure most scenarios without resorting to expression trees, especially if you can leverage structural equality for verifying arguments. For example:
let returns<'T> (value: 'T) x = x.Returns(value) |> ignore
[<Fact>]
let ``should call my activity``() =
task {
// Arrange
let context = Substitute.For<DurableOrchestrationContextBase>()
context.GetInput<SomeType>() |> returns { Foo = 42 }
// Act
do! runOrchestrator context
// Assert
// In C# you would have to do Arg.Is<SomeClass>(x => x.Bar == 43 && x.Baz == "bla")
do! context.Received().CallActivityAsync("MyActivity", { Bar = 43; Baz = "bla" })
}
Related
Is there a way to change the return value of the property accessor called when running unit tests? Like mocking the result of the property settingsState?
I am learning to create unit tests. What that class makes is to bring stored data into the program, this data is given in a visual form. In my test, I want to define what is going on there because the window won't open there.
// top-level declaration outside class
val settingsState: ApplicationSettingsState
get() = ServiceManager.getService(ApplicationSettingsState::class.java)
settingsState is not a variable. It is a property.
I am not aware of any way to mock global properties (or global functions). The way mocking works is to cleverly create an object that looks a bit like the object to mock from the outside, but behaves differently on the inside. In the absence of an object to mock, there is no way to mock.
That said, on the bytecode level there are no global variables, properties, whatever. They are all wrapped into classes, because the JVM likes it that way. Some clever bytecode manipulation might be able to achieve some effect – but not MockK.
You can mock the property if you have a mocked object. To paraphrase the documentation:
val mock = mockk(Bus())
every { mock getProperty "speed" } returns 33
Yes you can. You want to mock a property that is declared at top-level. Top-level code in a given Kotlin file MyFile.kt is actually compiled to be inside the class MyFileKt. Let's say we have following Kotlin file named MyFile.kt:
package foo
val bar = "some value"
If we compile this file to JVM bytecode and then decompile the result to Java, we get a Java class that looks similar to this:
package foo;
public final class MyFileKt {
private static final String bar = "some value";
public static final String getBar() {
return bar;
}
}
As you can see, our top-level val we defined earlier is actually translated to a static field with associated getter in the class MyFileKt.
TLDR; Getting back to our original problem, all you need to do is statically mock this field:
mockkStatic("foo.MyFileKt") // Fully-qualified name of the generated class
every { bar } returns "some other test value" // Define what our top-level property should return
The same also works for top-level functions, of course.
I'm using mockito 1.9.5.
I have the following code:
public class ClassA {
public List<? extends MyInterface> getMyInterfaces() {
return null;
}
public static void testMock() {
List<MyInterface> interfaces = new ArrayList<>();
ClassA classAMock = mock(ClassA.class);
when(classAMock.getMyInterfaces()).thenReturn(interfaces);
}
I get a compilation error for the thenReturn(interfaces) saying:
"The method thenReturn(List<capture#1-of ? extends MyInterface>) in the type
OngoingStubbing<List<capture#1-of ? extends MyInterface>> is not applicable for the arguments
(List<MyInterface>)"
However, when I use the thenAnswer method of mockito, I don't get the error. Can anyone tell me what's going on? Why do I get the error when I use the thenReturn method?
Is there any other way to solve this problem when ClassA is provided by a 3rd party and cannot be modified?
EDIT : Starting from Mockito 1.10.x, generics types that are embedded in the class are now used by Mockito for deep stubs. ie.
public interface A<T extends Observer & Comparable<? super T>> {
List<? extends B> bList();
T observer();
}
B b = deep_stubbed.bList().iterator().next(); // returns a mock of B ; mockito remebers that A returns a List of B
Observer o = deep_stubbed.observer(); // mockito can find that T super type is Observer
Comparable<? super T> c = deep_stubbed.observer(); // or that T implements Comparable
Mockito tries its best to get type information that the compiler embeds, but when erasure applies, mockito cannot do anything but return a mock of Object.
Original : Well that's more of an issue with generics than with Mockito. For generics, you should read what Angelika Langer wrote on them. And for the current topic, i.e. wildcards, read this section.
But for short, what you could use is the other syntax of Mockito to help with your current situation :
doReturn(interfaces).when(classAMock).getMyInterfaces();
Or with the BDD aliases :
willReturn(interfaces).given(classAMock).getMyInterfaces();
Nevertheless, you could write wrappers that are more generic friendly. That will help future developers working with same 3rd party API.
As a side note: you shouldn't mocks type you don't own, it can lead to many errors and issues. Instead you should have some wrapper. DAO and repositories for example represent such idea, one will mock the DAO or repository interface, but not the JDBC / JPA / hibernate stuff. There are many blog posts about that:
http://davesquared.net/2011/04/dont-mock-types-you-dont-own.html
http://blog.8thlight.com/eric-smith/2011/10/27/thats-not-yours.html
https://web.archive.org/web/20140923101818/http://freshbrewedcode.com/derekgreer/2012/04/01/tdd-best-practices-dont-mock-others/
...
Another solution (albeit less readable) is to qualify the static method call of when to bind the wildcard:
Mockito.<List<? extends MyInterface>>when(classAMock.getMyInterfaces()).thenReturn(interfaces);
This question is about dealing with testing of classes which mix in non-interface traits, that is traits containing some functionality. When testing, the class functionality should be isolated from the functionality provided by the mix-in trait (which is supposedly tested separately).
I have a simple Crawler class, which depends on a HttpConnection and a HttpHelpers collection of utility functions. Let's focus on the HttpHelpers now.
In Java, HttpHelpers would possibly be a utility class, and would pass its singleton to Crawler as a dependency, either manually or with some IoC framework. Testing Crawler is straightforward, since the dependency is easy to mock.
In Scala it seems that a helper trait is more preferred way of composing functionality. Indeed, it is easier to use (methods automatically imported into the namespace when extending, can use withResponse ... instead of httpHelper.withResponse ..., etc.). But how does it affect testing?
This is my solution I came up with, but unfortunately it lifts some boilerplate to the testing side.
Helper trait:
trait HttpHelpers {
val httpClient: HttpClient
protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
protected def makeGetRequest(url: String): HttpResponse = // ...
}
Code to test:
class Crawler(val httpClient: HttpClient) extends HttpHelpers {
// ...
}
Test:
// Mock support trait
// 1) Opens up protected trait methods to public (to be able to mock their invocation)
// 2) Forwards methods to the mock object (abstract yet)
trait MockHttpHelpers extends HttpHelpers {
val myMock: MockHttpHelpers
override def makeGetRequest(url: String): HttpResponse = myMock.makeGetRequest(url)
}
// Create our mock using the support trait
val helpersMock = Mockito.mock(classOf[MockHttpHelpers])
// Now we can do some mocking
val mockRequest = // ...
Mockito when (helpersMock.makeGetRequest(Matchers.anyString())) thenReturn mockRequest
// Override Crawler with the mocked helper functionality
class TestCrawler extends Crawler(httpClient) with MockHttpHelpers {
val myMock = helpersMock
}
// Now we can test
val crawler = new TestCrawler()
crawler.someMethodToTest()
Question
This approach does the work, but the need to have a mock support trait for each helper trait is a bit tedious. However I can't see any other way for this to work.
Is this the right approach?
If it is, could its goal be reached more efficiently (syntax magic, compiler plugin, etc)?
Any feedback is welcome. Thank you!
You can write an Helper mock trait which should be mixed with HttpHelpers and override its methods with mock equivalent:
trait HttpHelpersMock { this: HttpHelpers =>
//MOCK IMPLEMENTATION
override protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
//MOCK IMPLEMENTATION
override protected def makeGetRequest(url: String): HttpResponse = // ...
}
Then, when testing crawler, you mix the mock trait at instantiation:
val crawlerTestee = new Crawler(x) with HttpHelpersMock
And the mock methods will just replace the helper methods in instance crawlerTestee.
Edit: I don't think its a good idea to test how a class interacts with an helper trait. In my opinion, you should test Crawler behavior and not its internal implementation detail. Implementations can change but the behavior should stay as stable as possible. The process I described above allows you to override helper methods to make them deterministic and avoid real networking, thus helping and speeding tests.
However, I believe it make sense to test the Helper itself, since it may be reused elsewhere and has a proper behavior.
How about:
val helpers = new HttpHelpers {
//override or define stuff the trait needs to work properly here
}
helpers.someMethodToTest
Look, Ma, no intermediate traits and mocking libraries needed!
I do that all the time for my traits and I've been pretty happy with the result.
I'm trying to run the following code with Ninject.Moq:
[TestMethod]
public void TestMethod1()
{
var kernel = new MockingKernel();
var engine = kernel.Get<ABC>();
//as I don't need to actually use the interfaces, I don't want
//to even have to bother about them.
Assert.AreEqual<string>("abc", engine.ToString());
}
And here is the ABC class definition:
public class ABC {
IA a;
IB b;
public ABC(IA a, IB b)
{
this.a = board;
this.b = war;
}
public override string ToString()
{
return "abc";
}
}
I'm getting the following exception:
System.ArgumentException: A matching
constructor for the given arguments
was not found on the mocked type. --->
System.MissingMethodException:
Constructor on type
'AbcProxya759aacd0ed049f3849aaa75e2a7bade'
not found.
Ok, this will make the code work:
[TestMethod]
public void TestMethod1()
{
var kernel = new MockingKernel();
kernel.Bind<Abc>().ToSelf();
var engine = kernel.Get<ABC>();
//as I don't need to actually use the interfaces, I don't want
//to even have to bother about them.
Assert.AreEqual<string>("abc", engine.ToString());
}
One has to bind Abc to itself, otherwise it will also get mocked and Moq only supports mocking parameterless classes, which is not the case.
It's a bit like understanding DI in the first
place :- small samples don't really get the whole point across.
An automocking container like Ninject.Moq (or similar test infrastructure libraries like AutoFixture) is hard to really explain with a simple example. I'd suggest reading all of Mark Seemann's posts on AutoFixture as a way of getting a feel fro the requirement.
So Ninject.Moq will deal with the chaining, N levels deep of a set of stub implementations of interfaces that are necessary to satisfy your System Under Test in the course of doing the thing your test is actually supposed to be testing.
In general, you want short easy to read, easy to grok tests with minimal complexity and interaction of fixtures under the cover (no big hierarchy of base classes, or 6 different magic methods doing wacky teardown and calling base classes). Normally this aim will mean you should keep your DI toolery miles away from your unit tests.
An automocking container should, like a chainsaw, only be used where you're going to get a signnificant real return (many shorter, easier to understand tests) for you investment (another tool to understand before others can read you tests, more debugging, more surprises, more complexity that'll lead to brittle, unmaintainable tests).
Say I have an interface IFoo which I am mocking. There are 3 methods on this interface. I need to test that the system under test calls at least one of the three methods. I don't care how many times, or with what arguments it does call, but the case where it ignores all the methods and does not touch the IFoo mock is the failure case.
I've been looking through the Expect.Call documentation but can't see an easy way to do it.
Any ideas?
You can give rhino mocks a lambda to run when a function get's called. This lambda can then increment a counter. Assert the counter > 1 and you're done.
Commented by Don Kirkby:
I believe Mendelt is referring to the Do method.
Not sure this answers your question but I've found that if I need to do anything like that with Rhino (or any similiar framework/library), anything that I didn't know how to do upfront, then I'm better just creating a manual mock.
Creating a class that implements the interface and sets a public boolean field to true if any of the methods is called will be trivially easy, you can give the class a descriptive name which means that (most importantly) the next person viewing the code will immediately understand it.
If I understood you correctly you want to check that the interface is called at least once on any of three specified methods. Looking through the quick reference I don't think you can do that in Rhino Mocks.
Intuitively I think you're trying to write a test that is brittle, which is a bad thing. This implies incomplete specification of the class under test. I urge you to think the design through so that the class under test and the test can have a known behavior.
However, to be useful with an example, you could always do it like this (but don't).
[TestFixture]
public class MyTest {
// The mocked interface
public class MockedInterface implements MyInterface {
int counter = 0;
public method1() { counter++; }
public method2() { counter++; }
public method3() { counter++; }
}
// The actual test, I assume you have the ClassUnderTest
// inject the interface through the constructor and
// the methodToTest calls either of the three methods on
// the interface.
[TestMethod]
public void testCallingAnyOfTheThreeMethods() {
MockedInterface mockery = new MockedInterface();
ClassUnderTest classToTest = new ClassUnderTest(mockery);
classToTest.methodToTest();
Assert.That(mockery.counter, Is.GreaterThan(1));
}
}
(Somebody check my code, I've written this from my head now and haven't written a C# stuff for about a year now)
I'm interested to know why you're doing this though.