When I raised it from Java8u74 to 8u102, it seemed that I had to raise JMockit as well. The JMockit I'm using is too old, and I'm afraid that it will cause a compile error or a runtime error. I decided to summarize it as a memorandum.
Java8u102 (maybe 8u74 will work) maven3 series
change log It's mostly written, but sometimes I don't know how to actually write it. JMockit Development history
-JMockit usage memo I'm really grateful that it's mostly listed and how to write it in detail.
JMockit 1.4
pom.xml
<dependency>
<groupId>com.googlecode.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
JMockit 1.30 I'm afraid that even the group has changed. (Although it is common ...)
pom.xml
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.30</version>
<scope>test</scope>
</dependency>
It has been deprecated in Version 1.23 and deleted in Version 1.25.
Version 1.23 (Apr 24, 2016): Deprecated the NonStrictExpectations class. Existing tests should use Expectations instead.
Version 1.25 (Jun 26, 2016): Removed the NonStrictExpectations class, which was deprecated in version 1.23.
For the time being, I want to get rid of the compilation error, so I will change it blindly.
The usage of NonStrict Expectations is summarized in the following link (although it can not be used anymore) jMockit is good Verification
--Expectations Record all execution order, number of executions, etc. Quite strict. --NonStrictExpectations Loosen a little. Through whether it is executed or not.
There seems to be a difference like this. For details, please see the links below for easy understanding. Thanks. JMockit Usage Memo NonStrictExpectations This will be fixed later as it will fail when running the test.
Deprecated in Version 1.5 and "methods" and "inverse" attributes have been removed in Version 1.6.
Version 1.5 (Oct 20, 2013): Deprecated the "methods" and "inverse" attributes of @Mocked. Existing uses like @Mocked(methods = {"method1", "method2"}) should simply be rewritten as @Mocked({"method1", "method2"}) (using the default value attribute). As for the inverse attribute, specify what is to be mocked instead. Version 1.6 (Dec 23, 2013): Removed the "methods" and "inverse" attributes of the @Mocked annotation, which were deprecated in release 1.5. Tests still using "@Mocked(methods = {...}) should instead use the default "value" attribute.
This method will be removed in Version 1.19 even though I'm telling you to use @Mocked (methods = {...}) from now on. sad.
Version 1.19 (Aug 23, 2015): Removed the "value" attribute of @Mocked, which was deprecated in release 1.17. Existing tests using "@Mocked({"someMethod", "anotherMethod", ...})" should simply omit the attribute, or use partial mocking as applied with new Expectations(objToPartiallyMock) { ... }, or apply a MockUp
class.
There are various ways to write with the arguments of Expectations after that, so I do not know whether it can be used or not, so
Gently rewrite to MockUp
Before correction.java
@Test
public void test(@Mocked(methods="readLine") final BufferedReader br) {
new NonStrictExpectations() {
{
br.readLine();
result = new IOException();
}
};
}
Revised.java
@Test
public void test() { // MockUp<T>Since it is defined in, the argument is deleted. If there is, it will be an error
new MockUp<BufferedReader>() {
@Mock
public String readLine() throws IOException{
throw new IOException();
}
};
}
By the way, in this case of BufferedReader, it seems good to change @Mocked to @Injectable (or rather, both have the same result). I wonder which one is better. Click here for details → JMockit First Step @Injectable
It seems that it was the Invocations class that operated on setField, invoke and private people, but it seems that it was deleted in Version 1.6.
Version 1.6 (Dec 23, 2013): Removed all Reflection-based utility methods from the Invocations class (the base for Expectations and Verifications), in favor of using the static methods of identical signatures in the Deencapsulation class. This change in the API will not require any changes to test code, except that test classes using these methods should now include the following "static import": import static mockit.Deencapsulation.*;
Before correction.java
setField(hoge, "aaaa", "aaaa");
invoke((hoge, "privateMethod");
After change.java
Deencapsulation.setField(hoge, "aaaa", "aaaa");
Deencapsulation.invoke((hoge, "privateMethod");
By the way, if you try to set it in the private static final field, you may get angry with Can not set static final, so in that case It seems that the behavior of Deencapsulation.setField has changed yukiko-kato-bass/items/69b0c7b2417079345d37#deencapsulationsetfield%E3%81%AE%E6%8C%99%E5%8B%95%E3%81%8C%E5%A4%89%E3%82%8F%E3% 81% A3% E3% 81% 9F% E3% 82% 89% E3% 81% 97% E3% 81% 84).
Missing 1 invocation to: ~ Caused by: Missing invocations Now the moss is [Change NonStrictExpectations to Expectations](http://qiita.com/yukiko-kato-bass/items/69b0c7b2417079345d37#nonstrictexpectations%E3%82%92expectations%E3%81%AB%E5%A4% 89% E6% 9B% B4% E3% 81% 99% E3% 82% 8B). This method isn't called! I'm angry. Sir Sen. It's an error because the method recording became strict. As a workaround, set the minimum expected number of executions of the method to 0. By the way, if you want to explicitly show that it is not called, you can check with maxTimes = 0.
HogeTest.java
new Expectations() {{
hoge.method(); minTimes=0;
hoge.method2(); maxTimes=0;
}};
~~ Well, if you put this on, you won't know if it was called or not, so I think you should check that area with Verifications. ~~
The guy who writes this way now falls with a NullPointerException.
Before correction.java
@Test
public void test(@Mocked final HogeEnum hogeEnum) {
new Expectations() {
@Mocked
HogeEnum hogeEnum;
{
hogeEnum.getHoge();
result = "hogehoge";
}
};
Apparently it should be rewritten to MockUp. How to mock this in an Enum class using jmockt?
Revised.java
@Test
public void test() { //Since it is written in MockUp, delete the argument
new MockUp<HogeEnum>() {
@Mock
public String getHoge() {
return "/NOTHING/DATA.mf";
}
};
}
When I changed the one written like this from NonStrictExpectations to Expectations, it ended up failing.
Change before.java
@Test
public void test() throws Exception {
final Hoge hoge1 = new Hoge("hogehoge");
new NonStrictExpectations() {
{
test.getHoge("hogehoge");
result = hoge1;
}
};
assertThat(test.getHoge("hogehoge"), hoge1);
assertThat(test.getHoge("fugafuga"), null); //It won't be null here!
}
When I debugged, the Hoge instance itself was created. (Although value is null) If you look here, [JMockit usage memo Value returned by the method of the mocked object](http://qiita.com/opengl-8080/items/a49d4dae9067413ccdd6#%E3%83%A2%E3%83%83%E3 % 82% AF% E5% 8C% 96% E3% 81% 95% E3% 82% 8C% E3% 81% 9F% E3% 82% AA% E3% 83% 96% E3% 82% B8% E3% 82 % A7% E3% 82% AF% E3% 83% 88% E3% 81% AE% E3% 83% A1% E3% 82% BD% E3% 83% 83% E3% 83% 89% E3% 81% 8C % E8% BF% 94% E3% 81% 99% E5% 80% A4), so it's the behavior, but I want to change the object returned by the argument, or I want to return null when it is not a certain argument you know.
Explicitly specify the result when the arguments are different
amendment.java
@Test
public void test() throws Exception {
final Hoge hoge1 = new Hoge("hogehoge");
new Expectations() {
{
test.getHoge("hogehoge");
result = hoge1;
test.getHoge("fugafuga");
result = null;
}
};
assertThat(test.getHoge("hogehoge"), hoge1);
assertThat(test.getHoge("fugafuga"), null);
}
Rewriting of private static final fields worked in 1.4, but it seems that the behavior has changed, and java.lang.RuntimeException: java.lang.IllegalAccessException: Can not set static final ~ has come to occur. (The target to be set is not a primitive. The set is a Mock object.) Deencapsulation.setField() is broken for JDK8 after I upgrade to v1.24
Ok, I updated our tests to use a MockUp instead. This is cleaner anyway.
Eh, can you use MockUp? So, [Mock static initialization block](http://qiita.com/opengl-8080/items/a49d4dae9067413ccdd6#static-%E5%88%9D%E6%9C%9F%E5%8C% 96% E3% 83% 96% E3% 83% AD% E3% 83% 83% E3% 82% AF% E3% 82% 92% E3% 83% A2% E3% 83% 83% E3% 82% AF% I rewrote it using E5% 8C% 96% E3% 81% 99% E3% 82% 8B) as a reference.
Hoge.java
//Application is a self-made class
private final static Application application = Application.getInstance();
Before correction.java
Hoge hoge = new Hoge();
Deencapsulation.setField(Hoge.class , application);
Revised.java
new MockUp<Hoge>() {
@Mock
void $clinit() {
Deencapsulation.setField(Hoge.class ,hoge);
}
};
Is it possible to assign with $ clinic () even if it is not declared in a static block? A mystery.
Some of the invokes didn't work either. I don't know the difference between a moving one and a non-moving one. ..
PrivateHoge.java
//Suppose there is such a method
private Hoge getHoge() {
return hoge;
}
Before correction.java
new Expectations() {{
Deencapsulation.invoke(privateHoge, "getHoge");
}};
Rewrite using MockUp
Revised.java
new Expectations() {{
new MockUp<PrivateHoge>() {
@Mock
Hoge getHoge() {
return hogehoge;
}
};
}};
It seems that Deencapsulation.invoke can also be used if it is a Mockized method in MockUp. I'm saying NullPointer, so I wonder if I should make it explicit before invoking.
Amendment 2.java
new Expectations() {{
new MockUp<PrivateHoge>() {
@Mock
Hoge getHoge() {
Deencapsulation.invoke(privateHoge, "getHoge");
}
};
}};
Those who declared @Mocked instances in Expectations now return null. By the way, it seems that partial mocking is called Partial Mocking. really jMockit Verifications partial mocking
The one who got stuck.java
new Expectations(patternManager) {
@Mocked Hoge hoge;
{
System.out.println(hoge);
System.out.println(hoge.hoge);
In either.
[Constructor return value cannot be specified](http://qiita.com/opengl-8080/items/a49d4dae9067413ccdd6#%E3%82%B3%E3%83%B3%E3%82%B9%E3%83%88 % E3% 83% A9% E3% 82% AF% E3% 82% BF% E3% 81% AE% E6% 88% BB% E3% 82% 8A% E5% 80% A4% E3% 81% AF% E6 % 8C% 87% E5% AE% 9A% E3% 81% A7% E3% 81% 8D% E3% 81% AA% E3% 81% 84)
This is quite difficult and fighting
As shown in Accessing the invocation context, it seems that the $ init method can do the same processing as the constructor. You just have to match the signature.
HogeTest.java
new MockUp<File>() {
@Mock
void $init(File file, String path)
{
// new File(file, path)Can be mocked in the constructor of
}
By the way, if you add Invocation to the first argument, you can get a mock instance.
-JMockit First Step -[JMockit1.30] More details on argument matching in Expectations
Recommended Posts