キーとしてStringsを保持し、値としてクラスCandidate
の模擬インスタンスを保持するマップを作成したいとします。JMockitがクラスの複数のインスタンスをモックできません
Map<String, Long> domainNameToId = new HashMap<String, Long>();
domainNameToId.put("farmaciapuentezurita.es", 1234l);
domainNameToId.put("vivefarma.com", 2345l);
domainNameToId.put("eurofarmacia.com", 3456l);
Map<String, Candidate> expectedCandidates = new HashMap<String, Candidate>();
for(String domain : domainNameToId.keySet()) {
final Candidate cand = new MockUp<Candidate>() {
@Mock Long getDomainId() { return domainNameToId.get(domain); } // private method
@Mock boolean validateAndPrepare() { return true; }
@Mock String getRepresentingName() { return domain; }
}.getMockInstance();
expectedCandidates.put(domain, cand);
}
1.28に1.20からJMockitをアップグレードする前に働いて上記のコード。
今、私は例外を取得:
...でステートレスなモックアップ からクラスcom.urlservice.data.Candidateの初期化されていないインスタンスを取得するための不正な試みjava.lang.IllegalStateException:
は私がマニュアルを読み、以下の方法で代わりにnew MockUp(T targetInstance)
を使用しようとした(これは、ループの体である):
final Candidate cand = new Candidate(domain);
new MockUp<Candidate>(cand) {
@Mock Long getDomainId() { return domainNameToId.get(domain); } // private method
@Mock boolean validateAndPrepare() { return true; }
@Mock String getRepresentingName() { return domain; }
};
結果は非常に奇妙でした。最初の候補者は適切に嘲笑され、残りの嘲笑候補者はまったく嘲笑されず、実際の方法が呼び出されました。
java.lang.IllegalArgumentExceptionが::すでに嘲笑:クラスcom.urlservice.data.Candidate で無駄に
final Candidate cand = new Candidate(domain); new Expectations(cand) {{ cand.getDomainId(); result = domainNameToId.get(domain); // Had to make it public :-( cand.validateAndPrepare(); result = true; cand.getRepresentingName(); result = domain; }};
:
は、私は戻ってExpectations
APIに戻すことを試みました...
本当に最新バージョンにアップグレードしたいのですが、この問題の回避策が見つかりません。
更新日:この問題は、1.28までのバージョンで再現できませんでした。このバージョンが導入されたバージョンだと思います。
さらに、私の第2の例(new MockUp(T targetInstance)
)に関連して、私はクラスMockUp
行402のソースコードを見て、期待される振る舞いが最初のもの以外の特定のターゲットインスタンスをモックしないように見えます。
MockUp<?> previousMockUp = findPreviouslyFakedClassIfMockUpAlreadyApplied();
if (previousMockUp != null) {
targetType = previousMockUp.targetType;
mockedClass = previousMockUp.mockedClass;
return; // Input param targetInstance is disregarded
}
私は何が欠けていますか?
UPDATE2:私は失敗したテストの例を思いつきました。ちょっと面倒ですが、私はそれがポイントを得るだろうと確信しています。
public class SampleTest {
class TestedClass {
private IncrementingDependency dep;
TestedClass(IncrementingDependency dep) { this.dep = dep; }
public int getVal() { return dep.inc(); }
}
class IncrementingDependency {
int val;
public IncrementingDependency(int val) { this.val = val; }
public int inc() { return ++val; }
}
@Test
public void sampleTest() {
List<Integer> inputVals = Arrays.asList(1, 2, 3);
List<TestedClass> incrementingClasses = new ArrayList<TestedClass>();
for (Integer num : inputVals) {
IncrementingDependency dep = new IncrementingDependency(num);
new MockUp<IncrementingDependency>(dep) {
@Mock int inc() { return num; } // Mock with different behavior - DON'T INCREMENT
};
incrementingClasses.add(new TestedClass(dep));
}
assertThat(incrementingClasses.get(0).getVal()).isEqualTo(1); // Passes - 1 wasn't incremented (mocked behavior)
assertThat(incrementingClasses.get(1).getVal()).isEqualTo(2); // Fails - real code was called and 2 was incremented to 3
assertThat(incrementingClasses.get(2).getVal()).isEqualTo(3); // We never get to this point
}
}
この例では、失敗していません場合でも、私はMockUp
のコンストラクタに渡す前に、私の依存関係をインスタンス化する必要があるという事実は、せいぜい問題があることに注意してください。あなたがそれをインスタンス化する必要はないということですか?
'new MockUp(cand)'を使用しているときに「奇妙な」結果を再現できませんでした。それは1.28でうまくいくようです。失敗したサンプルテストを表示できますか? –
'Mock(T)'の[API documentation](http://jmockit.org/api1x/mockit/MockUp.html#MockUp-T-)には「指定されたインスタンスにのみ影響する」と記載されています。だから、 'Candidate'の* other *インスタンスに対して呼び出されたメソッドは' @ Mock'メソッドには行きません。 –
@Rogérioもちろん、それは私が達成しようとしていたものです。私は失敗したサンプルテストをできるだけ早く提供しようとしますが、最後にJMockitのコードサンプルを書いて、私の主張を強くバックアップしていませんか? – KidCrippler